【BZOJ3052&UOJ58】糖果公园(树上带修莫队)

题意:给定一个n个点的树,每个结点上有一种颜色c[i]

定义一条简单路径的偷税指数为simga (sigma w[i](i=0..a[j]))*v[j](j=0..m),其中a[i]为第i种颜色在路径上出现的次数

现在共有q个非强制在线的操作,格式为(op,x,y)

op=0时代表将x号点的颜色修改为y

op=1时询问(x,y)这条简单路径的偷税指数

思路:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 //typedef pair<ll,ll>P;
 11 #define N  200010
 12 #define M  200010
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pb push_back
 17 #define pi acos(-1)
 18 #define mem(a,b) memset(a,b,sizeof(a))
 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 21 #define lowbit(x) x&(-x)
 22 #define Rand (rand()*(1<<16)+rand())
 23 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 24 #define ls p<<1
 25 #define rs p<<1|1
 26 
 27 const int MOD=1e9+7,inv2=(MOD+1)/2;
 28       double eps=1e-4;
 29       int INF=0x7fffffff;
 30       int inf=1e9;
 31       int dx[4]={-1,1,0,0};
 32       int dy[4]={0,0,-1,1};
 33 
 34 struct Q
 35 {
 36     int l,r,cur,id;
 37 }q[M];
 38 
 39 struct P
 40 {
 41     int x,pre,now;
 42 }p[M];
 43 
 44 int head[N],vet[N],nxt[N],w[N],c[N],cnt[N],tot,
 45     f[N][20],l[N],r[N],pos[N],dfn[N],to[N],dep[N],v[N],vis[N],b[N],tim1,tim2;
 46 ll now,ans[N];
 47 
 48 bool cmp(Q a,Q b)
 49 {
 50    return pos[a.l]<pos[b.l]
 51         ||pos[a.l]==pos[b.l]&&pos[a.r]<pos[b.r]
 52         ||pos[a.l]==pos[b.l]&&pos[a.r]==pos[b.r]&&a.cur<b.cur;
 53 }
 54 
 55 int read()
 56 {
 57    int v=0,f=1;
 58    char c=getchar();
 59    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 60    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 61    return v*f;
 62 }
 63 
 64 void add(int a,int b)
 65 {
 66     nxt[++tot]=head[a];
 67     vet[tot]=b;
 68     head[a]=tot;
 69 }
 70 
 71 void dfs(int u,int fa)
 72 {
 73     rep(i,1,17) f[u][i]=f[f[u][i-1]][i-1];
 74     dfn[u]=++tim1;
 75     l[u]=++tim2; to[tim2]=u;
 76     int e=head[u];
 77     while(e)
 78     {
 79         int v=vet[e];
 80         if(v!=fa)
 81         {
 82             dep[v]=dep[u]+1;
 83             f[v][0]=u;
 84             dfs(v,u);
 85         }
 86         e=nxt[e];
 87     }
 88     r[u]=++tim2; to[tim2]=u;
 89 }
 90 
 91 int lca(int x,int y)
 92 {
 93     if(dep[x]<dep[y]) swap(x,y);
 94     int d=dep[x]-dep[y];
 95     rep(i,0,17)
 96      if(d>>i&1) x=f[x][i];
 97     per(i,17,0)
 98      if(f[x][i]!=f[y][i])
 99      {
100          x=f[x][i];
101          y=f[y][i];
102      }
103     if(x==y) return x;
104     return f[x][0];
105 }
106 
107 void go(int x)
108 {
109     if(vis[x])
110     {
111         now-=1ll*v[c[x]]*w[cnt[c[x]]];
112         cnt[c[x]]--;
113     }
114      else
115      {
116          cnt[c[x]]++;
117          now+=1ll*v[c[x]]*w[cnt[c[x]]];
118      }
119     vis[x]^=1;
120 }
121 
122 void update(int x,int y)
123 {
124     if(vis[x])
125     {
126         go(x);
127         c[x]=y;
128         go(x);
129     }
130      else c[x]=y;
131 }
132 
133 int main()
134 {
135     int n=read(),m=read(),k=read();
136     int S=max(10,(int)pow(n,2.0/3));
137     rep(i,1,m) v[i]=read();
138     rep(i,1,n) w[i]=read();
139     tot=0;
140     rep(i,1,n) head[i]=0;
141     rep(i,1,n-1)
142     {
143         int x=read(),y=read();
144         add(x,y);
145         add(y,x);
146     }
147     rep(i,1,n)
148     {
149         c[i]=read();
150         b[i]=c[i];
151     }
152 
153     tim1=tim2=0;
154     dfs(1,0);
155     rep(i,1,tim2) pos[i]=(i-1)/S;
156     int l1=0,l2=0;
157     rep(i,1,k)
158     {
159         int op=read(),x=read(),y=read();
160         if(op==0)
161         {
162             l2++;
163             p[l2].x=x;
164             p[l2].pre=b[x];
165             p[l2].now=b[x]=y;
166         }
167          else
168          {
169              l1++;
170              if(dfn[x]>dfn[y]) swap(x,y);
171              int t=lca(x,y);
172              if(t==x) q[l1].l=l[x];
173               else q[l1].l=r[x];
174              q[l1].r=l[y];
175              q[l1].id=l1;
176              q[l1].cur=l2;
177          }
178     }
179     sort(q+1,q+l1+1,cmp);
180     int L=1,R=0,T=0;
181     now=0;
182     rep(i,1,l1)
183     {
184         while(T<q[i].cur)
185         {
186             T++;
187             update(p[T].x,p[T].now);
188         }
189         while(T>q[i].cur)
190         {
191             update(p[T].x,p[T].pre);
192             T--;
193         }
194         while(L>q[i].l) go(to[--L]);
195         while(L<q[i].l) go(to[L++]);
196         while(R>q[i].r) go(to[R--]);
197         while(R<q[i].r) go(to[++R]);
198         int x=to[L],y=to[R],t=lca(x,y);
199         if(x!=t&&y!=t) go(t);
200         ans[q[i].id]=now;
201         if(x!=t&&y!=t) go(t);
202     }
203     rep(i,1,l1) printf("%lld\n",ans[i]);
204     return 0;
205 }

猜你喜欢

转载自www.cnblogs.com/myx12345/p/11636669.html