[SDOI2016Round1] [solution Report]
Day1 T1:
Question: Please Σ n? 1i = 0 Sigma m? 1j = 0max (ixorj )? K, 0)
Because each operator is independent, the contribution of one operator can be calculated.
F [I] [a] [B] [c] Indicates the I-th digit. N, m, k 0 indicates less than, 1 indicates equal before I, 2 indicates greater. At the time of transfer, what is the number of the current position of the American TV series, just move from the high position to the low position.
Complexity is O (nlogn)
Code:
#include
#include
#include
#includeusing namespace std;#define LL long long const int N=100;int T,Mod,ni[N],mi[N],ki[N],len;LL n,m,K,f[N][2][2][3],g[N][2][2][3];inline void calc(){ int i,a,b,c,o0,o1,x,y,z,o; g[0][1][1][1]=1; for(i=0;i
ni[i+1]) continue; if(o0==ni[i+1]) x=1; if(o0
mi[i+1]) continue; if(o1==mi[i+1]) y=1; if(o1
ki[i+1]) z=2; if(o==ki[i+1]) z=1; if(o
>=1) ni[++ni[0]]=x&1LL; for(x=m;x;x>>=1) mi[++mi[0]]=x&1LL; for(x=K;x;x>>=1) ki[++ki[0]]=x&1LL; len=max(ni[0],max(mi[0],ki[0])); for(i=1;i<=(len>>1);++i){ swap(ni[i],ni[len-i+1]); swap(mi[i],mi[len-i+1]); swap(ki[i],ki[len-i+1]); } calc(); printf("%lld\n",(f[len][0][0][2]-(K%Mod*g[len][0][0][2])%Mod+Mod)%Mod); }}
T2:
N types of numbers are given. The I-TH is ai, the number is bi, and the weight is ci. If Ai | aj And Aiaj Is a prime number, then the two numbers can be obtained Ci? Cj The maximum number of pairs must be obtained if the total value is not less than 0.
The pairing relationship is a bipartite graph. Therefore, a cost flow graph is created to process the current traffic and exit when the fee is less than 0.
Code:
#include
#include
#include
#includeusing namespace std;#define T n+2#define D 795#define LL long long #define inf 1000000000#define INF 10000000000000LLconst int N=800;const int M=100000;const int O=2000000;bool flag[M+10],use[N],f[N];struct S{int st,en,va;LL co;}aa[O];int n,a[N],b[N],c[N],prime[M+10],d[N],va,point[N],pre[N],next[O],map[N][N],tot=1,co[N];int l[N],to[N];LL dis[N];inline void prepare(){ int i,j; for(i=2;i<=M;++i){ if(!flag[i]) prime[++prime[0]]=i; for(j=1;j<=prime[0]&&i*prime[j]<=M;++j){ flag[i*prime[j]]=true; if(i%prime[j]==0) break; } }}inline void add(int x,int y,int z,LL co){ next[++tot]=point[x];point[x]=tot; aa[tot].st=x;aa[tot].en=y;aa[tot].va=z;aa[tot].co=co; next[++tot]=point[y];point[y]=tot; aa[tot].st=y;aa[tot].en=x;aa[tot].va=0;aa[tot].co=-co;}inline bool check(int x,int y){ int i,j,now,num=0; if((a[x]%a[y])||(a[x]==a[y])) return false; now=a[x]/a[y]; for(i=1;i<=prime[0];++i){ while(now%prime[i]==0) ++num,now/=prime[i]; if(num>1) return false; if(now==1) return true; } if(now!=1) ++num; return num==1;}inline void paint(int x,int kind){ int i; co[x]=kind; for(i=1;i<=n;++i) if(map[x][i]&&!co[i]) paint(i,kind==1?2:1);}inline LL SPFA(int x,int y){ int h=0,t=1,i,u; l[t]=x; for(i=1;i<=T;++i) dis[i]=-INF; dis[x]=0; while(h!=t){ h=h%D+1;u=l[h];f[u]=true; for(i=point[u];i;i=next[i]) if(aa[i].va>0&&dis[aa[i].en]
T3: A tree is given, with a bit of power and edge power. There are two kinds of operations: one is to change the vertex power on a path Min (v [x],? Dis [x] + B) , Dis [x] The distance from x to the start point (only edge weight is calculated ). The other is to query the minimum vertex weights in path a to path B.
The first modification can be seen as adding a line segment to a section of the tree. This item can be maintained using a line segment tree. Use the line segment tree to maintain the slope and intercept of the line segment in this interval. Each time you add a new line segment to this interval, You can see which of the original line segments and the new line segments in this interval have a greater impact on this interval, place a line segment that has a small impact on the child tree that has an impact, and place it on the leaf node every time. In this way, the complexity of each insert operation is O (log2n) .
For each query, you only need to check the minimum value in the interval and the two endpoints of the saved line segments. The complexity is O (logn) .
We still don't know about the dis array each time. We can pass in the lca when adding a line segment (the constant is much larger ...)
In addition, the overall complexity is O (nlog3n)
Code:
#include
#include
#include
#includeusing namespace std;#define mid (l+r)/2#define L k<<1,l,mid#define R k<<1|1,mid+1,r#define LL long long#define D 123456789123456789LLconst int N=100010;LL dis[N],a,b;struct S{int st,en,va;}aa[N<<1];struct T{int lca,st,kind;LL k,b,minn;}tr[N<<2];int n,m,point[N],next[N<<1],tot,deep[N],siz[N],son[N],belong[N],fa[N][21],q[N],pos[N],dfsn,cur[N],lca,to[N],flag[N<<2];inline int in(){ int f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f;}inline int IN(){ LL f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f;}inline void add(int x,int y,int z){ next[++tot]=point[x];point[x]=tot; aa[tot].st=x;aa[tot].en=y;aa[tot].va=z; next[++tot]=point[y];point[y]=tot; aa[tot].st=y;aa[tot].en=x;aa[tot].va=z;}inline void prepare(){ int h=1,t=1,u,i,j; q[h]=1; while(h<=t){ u=q[h]; for(i=point[u];i;i=next[i]) if(aa[i].en!=fa[u][0]){ q[++t]=aa[i].en; deep[aa[i].en]=deep[u]+1; fa[aa[i].en][0]=u; dis[aa[i].en]=dis[u]+(LL)aa[i].va; for(j=1;j<=20;++j) fa[aa[i].en][j]=fa[fa[aa[i].en][j-1]][j-1]; } h+=1; } for(i=t;i;--i){ u=q[i];siz[u]=1; for(j=point[u];j;j=next[j]) if(aa[j].en!=fa[u][0]){ siz[u]+=siz[aa[j].en]; if(siz[aa[j].en]>siz[son[u]]) son[u]=aa[j].en; } } int now=1; for(i=1;i<=n;++i) cur[i]=point[i]; while(now){ if(!pos[now]){ pos[now]=++dfsn; to[dfsn]=now; belong[now]=(now==son[fa[now][0]] ? belong[fa[now][0]] : now); now=(son[now] ? son[now] : fa[now][0]); } else{ for(i=cur[now];i&&(aa[i].en==fa[now][0]||aa[i].en==son[now]);i=next[i]); cur[now]=next[i]; belong[aa[i].en]=aa[i].en; now=(i ? aa[i].en : fa[now][0]); } }}inline int LCA(int x,int y){ if(deep[x]
=r){ LL minn=D; minn=min(minn,calc(l,now.lca,now.st,now.kind)*now.k+now.b); minn=min(minn,calc(r,now.lca,now.st,now.kind)*now.k+now.b); now.minn=tr[k].minn=min(tr[k].minn,minn); if(!flag[k]){ flag[k]=1; tr[k]=now; return ; } int o1=calc(l,now.lca,now.st,now.kind)*now.k+now.b
mid) insert(R,x,y,now); tr[k].minn=min(tr[k].minn,min(tr[k<<1].minn,tr[k<<1|1].minn));}inline LL query(int k,int l,int r,int x,int y){ LL minn=D; if(x<=l&y>=r){ LL o_l=calc(l,tr[k].lca,tr[k].st,tr[k].kind); LL o_r=calc(r,tr[k].lca,tr[k].st,tr[k].kind); return min(tr[k].minn,min(o_l*tr[k].k+tr[k].b,o_r*tr[k].k+tr[k].b)); } minn=min(minn,calc(max(x,l),tr[k].lca,tr[k].st,tr[k].kind)*tr[k].k+tr[k].b); minn=min(minn,calc(min(y,r),tr[k].lca,tr[k].st,tr[k].kind)*tr[k].k+tr[k].b); if(x<=mid) minn=min(minn,query(L,x,y)); if(y>mid) minn=min(minn,query(R,x,y)); return minn;}inline void change(int x,int y,int st,int kind){ int i,j; T now=(T){lca,st,kind,a,b,D}; while(belong[x]!=belong[y]){ insert(1,1,n,pos[belong[x]],pos[x],now); x=fa[belong[x]][0]; } insert(1,1,n,pos[y],pos[x],now);}inline LL ask(int x,int y){ LL minn=D; while(belong[x]!=belong[y]){ minn=min(minn,query(1,1,n,pos[belong[x]],pos[x])); x=fa[belong[x]][0]; } minn=min(minn,query(1,1,n,pos[y],pos[x])); return minn;}int main(){ int i,j,x,y,t,z; n=in();m=in(); for(i=1;i
Day2: T1: Question: Add a character to the end of a string each time to output the current number of different non-empty substrings.
First, read all the strings, and then create a suffix array. The answer is N? (N + 1) 2? Σ n? 1i = 1 height [I]
Because dynamic query is required, a rank weight line segment tree is maintained. Each time a line segment tree is added, the system queries the front and back ends. The answer to each update is: N? I? Lcp (now, pre )? Lcp (now, sub) + lcp (pre, sub)
Code:
#include
#include
#include
#includeusing namespace std;#define LL long long#define inf 0x7fffffffconst int N=100010;struct S{int minn,maxn;}tr[N<<2];int n,a[N],b[N],m,t1[N],t2[N],sa[N],rank[N],c[N],height[N],st[N][21],Log[N];inline int in(){ int x=0;char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x;}inline bool cmp(int *y,int p,int q,int k){ int o0,o1; o0=(p+k>=n)?-1:y[p+k]; o1=(q+k>=n)?-1:y[q+k]; return o0==o1&&y[p]==y[q];}inline void build_sa(){ int i,k,p,*x=t1,*y=t2; for(i=0;i
=k) y[p++]=sa[i]-k; for(i=0;i
=n) break; }}inline void build_height(){ int i,j,k=0; for(i=0;i
=r) return tr[k]; if(x<=mid) ans1=query(L,x,y),f1=true; if(y>mid) ans2=query(R,x,y),f2=true; if(f1&&f2) return update(ans1,ans2); else return f1?ans1:ans2;}int main(){ int i; n=in(); for(i=n-1;~i;--i) a[i]=b[i]=in(); sort(b+1,b+n+1); m=unique(b+1,b+n+1)-b-1; for(i=0;i
T2: Question: The number of n-length sequences must be 1 ~ N appears only once, and the number of m is equal A [I] = I .
The answer is C (n, m )? F [n? M]
C (n, m) Indicates the number of m solutions that meet the conditions. N? M The number of solutions in different positions, that is, the error message.
The formula for the wrong shot is: F [I] = (I? 1 )? (F [I? 1] + f [I? 2])
We need to pre-process the factorial when performing c.
Code:
#include
#include
#include
using namespace std;#define LL long long#define Mod 1000000007LLconst int M=1000000;LL f[M+10],g[M+10];int T,n,m;inline int in(){ int x=0;char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x;}inline LL quickpow(LL x,LL y){ LL ans=1; while(y){ if(y&1LL) ans=(ans*x)%Mod; y>>=1LL; x=(x*x)%Mod; } return ans;}int main(){ int i; T=in(); for(f[1]=0LL,f[2]=1LL,f[0]=1LL,i=3;i<=M;++i) f[i]=(LL)(i-1)*((f[i-1]+f[i-2])%Mod)%Mod; for(g[1]=g[0]=1LL,i=2;i<=M;++i) g[i]=(g[i-1]*(LL)i)%Mod; while(T--){ n=in();m=in(); if(m>n){ printf("0\n"); continue; } LL ans=f[n-m]*((g[n]*quickpow(g[m],Mod-2)%Mod)*quickpow(g[n-m],Mod-2)%Mod)%Mod; printf("%lld\n",ans); }}
T3: Question: There is a sequence with a length of n. Each node has a weight value divided into m portions, and the Minimum Variance of m portions is estimated. Answer requirements ? M2 .
Ans = m? Σ mi = 1 (xi? X rows) 2
= M? Σ mi? 1 (xi2 + x limit 2? 2xi? X rows)
Set Σ After the split, the next two items are constants, which is equivalent to finding the maximum sum of squares of each segment. This item can be slope optimized.
Code:
#include
#include
#include
using namespace std;#define LL long longconst int N=3010;LL f[N][N],a[N];int n,m,h[N],t[N],q[N][N];inline LL pow(LL x){return x*x;}inline LL get_son(int x,int y,int z){ return f[z][x]+pow(a[x])-f[z][y]-pow(a[y]);}inline LL get_fa(int x,int y){ return a[x]-a[y];}inline LL calc(int x,int y,int z){ return f[z][x]+pow(a[y]-a[x]);}int main(){ int i,j; scanf("%d%d",&n,&m); for(i=1;i<=n;++i) scanf("%lld",&a[i]),a[i]+=a[i-1]; memset(f,127/3,sizeof(f)); for(j=0;j<=m;++j) f[j][0]=0,q[j][h[j]=t[j]=1]=0; for(j=1;j<=m;++j) for(i=1;i<=n;++i){ while(h[j-1]