bzoj3052

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3052

题目大意:自己看看,懒得写

题解:带修改的树上莫队,经典爆评测机的题

代码:

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<cmath>
  6 #define maxn 100100
  7 #define ll long long 
  8 using namespace std;
  9 int n,m,q,blo;
 10 ll ans;
 11 int tot,top,totc,totq,lydsytime,belong;
 12 int bin[20],deep[maxn],fa[maxn][20],dfn[maxn];
 13 int z[maxn];
 14 int num[maxn];
 15 int now[maxn],v[maxn*2],pre[maxn*2];
 16 int pos[maxn];
 17 ll res[maxn],val[maxn],c[maxn],cpre[maxn],w[maxn];
 18 bool vis[maxn];
 19 struct data{
 20     int x,y,t,id;
 21     ll pre;
 22 }cg[maxn],bg[maxn];
 23 int read()
 24 {
 25     int x=0; char ch; bool bo=0;
 26     while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') bo=1;
 27     while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9');
 28     if (bo) return -x; return x;
 29 }
 30 bool cmp(data a,data b)
 31 {
 32     if (pos[a.x]==pos[b.x]) return dfn[a.y]<dfn[b.y]; return pos[a.x]<pos[b.x];
 33 }
 34 void ins(int a,int b){++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b;
 35 }
 36 void prework(){ 
 37     bin[0]=1;
 38     for (int i=1; i<=20; i++) bin[i]=bin[i-1]*2;
 39 }
 40 int dfs(int x)
 41 {
 42     int size=0;
 43     dfn[x]=++lydsytime;
 44     for (int i=1; i<=16; i++)
 45         if (deep[x]>=bin[i])
 46             fa[x][i]=fa[fa[x][i-1]][i-1];
 47         else 
 48             break;
 49     for (int p=now[x]; p; p=pre[p])
 50     {
 51         int son=v[p];
 52         if (son==fa[x][0]) continue;
 53         deep[son]=deep[x]+1;
 54         fa[son][0]=x;
 55         size+=dfs(son);
 56         if (size>blo)
 57         {
 58             belong++;
 59             for (int i=1; i<=blo; i++) pos[z[top--]]=belong;
 60             size=0;
 61         }
 62     }
 63     z[++top]=x;
 64     return size+1;
 65 }
 66 int lca(int x,int y)
 67 {
 68 //    cout<<" pre "<<x<<" "<<y<<endl;
 69     if (deep[x]<deep[y]) swap(x,y);
 70     int t=deep[x]-deep[y];
 71     for (int i=0; bin[i]<=t; i++)
 72         if (bin[i]&t)
 73         x=fa[x][i];
 74     for (int i=17; i>=0; i--)
 75         if (fa[x][i]!=fa[y][i])
 76             x=fa[x][i], y=fa[y][i];
 77 //    cout<<" now "<<x<<" "<<y<<endl;
 78     if (x==y) return x;
 79     return fa[x][0];
 80 }
 81 void reverse(int x)
 82 {
 83     //cout<<"                                         re "<<x<<" "<<c[x]<<" "<<val[c[x]]<<" "<<num[c[x]]<<" "<<w[num[c[x]]+1]<<" "<<w[1]<<endl;
 84     if (vis[x]) ans-=val[c[x]]*w[num[c[x]]],num[c[x]]--;
 85     else num[c[x]]++,ans+=val[c[x]]*w[num[c[x]]];
 86     vis[x]^=1;
 87 }
 88 void work(int u,int v)
 89 {
 90     //cout<<"             pre u v     "<<u<<" "<<v<<endl;
 91     while (u!=v)
 92     {
 93         if (deep[u]>deep[v])
 94         {
 95             reverse(u);
 96             u=fa[u][0];
 97         }
 98         else
 99         {
100             reverse(v);
101             v=fa[v][0];
102         }
103         //cout<<" now u v "<<u<<" "<<v<<" "<<endl;
104     }
105 }
106 void change(int x,int y)
107 {
108     if (vis[x])
109     {
110         reverse(x);
111         c[x]=y;
112         reverse(x);
113     }
114     else c[x]=y;
115 }
116 void init()
117 {
118     n=read(); m=read(); q=read();
119     blo=pow(n,2.0/3)*0.5;
120     for (int i=1; i<=m; i++) val[i]=read();
121     for (int i=1; i<=n; i++) w[i]=read();
122     for (int i=1; i<n; i++)
123     {
124         int u=read(),v=read();
125         ins(u,v); ins(v,u);
126     }
127     dfs(1);
128     //for (int i=1; i<=n; i++) cout<<"           dsdsd   "<<fa[i][0]<<" "<<dfn[i]<<endl;
129     belong++;
130     while (top) pos[z[top--]]=belong;
131     for (int i=1; i<=n; i++) c[i]=cpre[i]=read();
132     for (int i=1; i<=q; i++)
133     {
134         int type=read(),x=read(),y=read();
135         if (!type)
136         {
137             totc++; cg[totc].x=x,cg[totc].y=y,cg[totc].pre=cpre[x],cpre[x]=y;
138         }
139         else
140         {
141             totq++; bg[totq].x=x,bg[totq].y=y,bg[totq].t=totc; bg[totq].id=totq;
142         }    
143     }
144     sort(bg+1,bg+totq+1,cmp);
145     /*for (int i=1; i<=totq; i++)
146     {
147         cout<<" "<<bg[i].x<<" "<<bg[i].y<<" "<<bg[i].t<<" "<<endl;
148     }*/
149 }
150 void solve()
151 {
152     for (int i=1; i<=bg[1].t; i++) change(cg[i].x,cg[i].y);
153     work(bg[1].x,bg[1].y); 
154     int t=lca(bg[1].x,bg[1].y); 
155     //cout<<" "<<t<<" "<<bg[1].x<<" "<<bg[1].y<<endl;
156     reverse(t); res[bg[1].id]=ans; reverse(t);
157     for (int i=2; i<=totq; i++)
158     {
159         for (int j=bg[i-1].t+1; j<=bg[i].t; j++)
160             change(cg[j].x,cg[j].y);
161         for (int j=bg[i-1].t+1; j>bg[i].t; j--)
162             change(cg[j].x,cg[j].pre);
163         work(bg[i-1].x,bg[i].x); work(bg[i-1].y,bg[i].y);
164         int t=lca(bg[i].x,bg[i].y);
165         reverse(t); res[bg[i].id]=ans; reverse(t);
166     }
167 }
168 int main()
169 {
170     prework();
171     init();
172     solve();
173     for (int i=1; i<=totq; i++)
174         printf("%lld
",res[i]);
175 }
176 /*
177 4 3 5
178 1 9 2
179 7 6 5 1
180 2 3
181 3 1
182 3 4
183 1 2 3 2
184 1 1 2
185 1 4 2
186 0 2 1
187 1 1 2
188 1 4 2
189 */
View Code

一次CE,一次WA,一次AC

-------------哦,对了这道题还是有个坑,就是怎么推出带修改的树上莫队时间复杂度!待zfy来教我补!

原文地址:https://www.cnblogs.com/HQHQ/p/5574699.html