首页 > 代码库 > BZOJ3052: [wc2013]糖果公园

BZOJ3052: [wc2013]糖果公园

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3052

题解:700T刷道有分量的题。。。

        其实不加修改操作和苹果树是一样的。加上之后我们可以对每个询问加上一维时间,然后balabala。

        为什么块要取n^2/3?

        VFleaKing:

        

取B = n ^ (2 / 3),设 nBlo为块的个数,用bloNum[v]来代表v所在块的编号。(block number)

则同一个块内任意两结点的距离为O(n ^ (2 / 3))的。

按照之前我说的方式对询问进行排序,按顺序作答。

注意到(bloNum[curV], bloNum[curU])一共有nBlo ^ 2个取值。

那么如果移动一次,curV还在原来的块,curU还在原来的块,这种移动的总时间复杂度是O(nBlo ^ 2 * q)的。(因为curTi还要移动)

如果移动一次,curV不在原来的块,curU不在原来的块,这种移动发生的次数最多为 nBlo ^ 2。因为我是排好序的了嘛,相同块的是放在一起的。而这种移动发生一次最坏是O(n + n + q) = O(n)。(n、q是同阶的)

所以这样回答所有询问,时间复杂度就是O(nBlo ^ 2 * n)的。

由于B = n ^ (2 / 3),块的大小介于[B, 3 * B]之间。

则nBlo = O(n ^ (1 / 3))

则时间复杂度为O(n ^ (5 / 3))。

        

       1A简直不能更爽。

代码:

技术分享
  1 #include<cstdio>  2 #include<cstdlib>  3 #include<cmath>  4 #include<cstring>  5 #include<algorithm>  6 #include<iostream>  7 #include<vector>  8 #include<map>  9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 100000+5 14 #define maxm 100000+5 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 22 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 23 #define mod 1000000007 24 using namespace std; 25 inline int read() 26 { 27     int x=0,f=1;char ch=getchar(); 28     while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();} 29     while(ch>=0&&ch<=9){x=10*x+ch-0;ch=getchar();} 30     return x*f; 31 } 32 int n,m,k,tot,cnt,f[maxn][18],bin[20],dfn[maxn],ti,belong[maxn],top,sta[maxn]; 33 int l,r,t,s[maxn],v[maxn],w[maxn],dep[maxn],head[maxn],size,c[maxn],pre[maxn]; 34 bool vis[maxn]; 35 ll ret,ans[maxn]; 36 struct rec{int x,y,id,t;}a[maxn],b[maxn]; 37 struct edge{int go,next;}e[2*maxn]; 38 inline void add(int x,int y) 39 { 40     e[++tot]=(edge){y,head[x]};head[x]=tot; 41     e[++tot]=(edge){x,head[y]};head[y]=tot; 42 } 43 inline void dfs(int x) 44 { 45     dfn[x]=++ti;int tmp=top; 46     for1(i,17)if(bin[i]<=dep[x])f[x][i]=f[f[x][i-1]][i-1];else break; 47     for4(i,x)if(y!=f[x][0]) 48     { 49         dep[y]=dep[x]+1;f[y][0]=x;dfs(y); 50         if(top-tmp>=size) 51         { 52             ++cnt; 53             while(top!=tmp)belong[sta[top--]]=cnt; 54         } 55     } 56     sta[++top]=x; 57 } 58 inline int lca(int x,int y) 59 { 60     if(dep[x]<dep[y])swap(x,y); 61     int t=dep[x]-dep[y]; 62     for0(i,17)if(t&bin[i])x=f[x][i]; 63     if(x==y)return x; 64     for3(i,17,0)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i]; 65     return f[x][0]; 66 } 67 inline void change(int x) 68 { 69     if(vis[x]){ret-=(ll)w[s[c[x]]]*v[c[x]];s[c[x]]--;} 70     else {s[c[x]]++;ret+=(ll)w[s[c[x]]]*v[c[x]];} 71     vis[x]^=1; 72 } 73 inline void work(int x,int y) 74 { 75     while(x!=y) 76     { 77         if(dep[x]<dep[y])swap(x,y); 78         change(x); 79         x=f[x][0]; 80     } 81 } 82 inline void color(int x,int y) 83 { 84     if(!vis[x])c[x]=y; 85     else  86     { 87         change(x); 88         c[x]=y; 89         change(x); 90     } 91 }     92 inline bool cmp(rec a,rec b){return belong[a.x]==belong[b.x]?dfn[a.y]<dfn[b.y]:belong[a.x]<belong[b.x];} 93 int main() 94 { 95     freopen("input.txt","r",stdin); 96     freopen("output.txt","w",stdout); 97     n=read();m=read();k=read(); 98     bin[0]=1;for1(i,17)bin[i]=bin[i-1]<<1; 99     for1(i,m)v[i]=read();100     for1(i,n)w[i]=read();101     for1(i,n-1)add(read(),read());102     size=pow(n,0.666);103     dfs(1);104     while(top)belong[sta[top--]]=cnt;105     for1(i,n)pre[i]=c[i]=read();106     int c1=0,c2=0;107     for1(i,k)108     {109         int op=read();110         if(op){a[++c1].x=read(),a[c1].y=read(),a[c1].id=c1,a[c1].t=c2;if(belong[a[c1].x]>belong[a[c1].y])swap(a[c1].x,a[c1].y);}111         else b[++c2].x=read(),b[c2].y=read(),b[c2].id=pre[b[c2].x],pre[b[c2].x]=b[c2].y;112     }113     sort(a+1,a+c1+1,cmp);114     l=r=1,t=0;115     for1(i,c1)116     {117         while(t<a[i].t)t++,color(b[t].x,b[t].y);118         while(t>a[i].t)color(b[t].x,b[t].id),t--;119         work(l,a[i].x);work(r,a[i].y);120         l=a[i].x;r=a[i].y;int f=lca(l,r);121         change(f);122         ans[a[i].id]=ret;123         change(f);124     }125     for1(i,c1)printf("%lld\n",ans[i]);126     return 0;127 }
View Code

 

 

BZOJ3052: [wc2013]糖果公园