【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 }
null