码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3052: [wc2013]糖果公园

时间:2015-01-31 14:25:26      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

题目: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]糖果公园

标签:

原文地址:http://www.cnblogs.com/zyfzyf/p/4263952.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!