BZOJ3052: [wc2013]糖果公园
$n \leq 100000$的树,每个点有个糖,$m \leq 100000$种糖,每种糖好吃度$V_i$,吃$j$颗$i$糖会得到愉悦值$V_i*W_j$,$q \leq 100000$个操作:修改一个点上的糖;查询某条链上吃糖的愉悦值。
首先看看能不能用啥数据结构维护。麻烦。好上莫队。
树上的莫队,用dfs的入栈+出栈序可以变区间查询,查询$x$和$y$时,分$x$是否是$y$的祖先、$y$是否是$x$的祖先、两个都不是彼此祖先来查。
莫队的主要复杂度在修改,所以修改只要稍微改一点点东西都会快很多。比如我少了个if就快了10秒。好不卡了没意思。
1 //#include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 //#include<queue> 6 //#include<time.h> 7 //#include<complex> 8 #include<algorithm> 9 #include<stdlib.h> 10 using namespace std; 11 12 int n,m,lq,bl,tot,lc; 13 #define maxn 200011 14 int V[maxn],W[maxn],cnt[maxn],a[maxn],bel[maxn]; 15 struct Ques{int l,r,t,id,biu;}q[maxn]; 16 bool cmp(const Ques &a,const Ques &b) {return bel[a.l]==bel[b.l]?(bel[a.r]==bel[b.r]?a.t<b.t:a.r<b.r):a.l<b.l;} 17 struct Modi{int x,a,b;}mo[maxn]; 18 19 struct Edge{int to,next;}edge[maxn<<1]; int first[maxn],le=2; 20 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;} 21 void insert(int x,int y) {in(x,y); in(y,x);} 22 23 int A[maxn],B[maxn],list[maxn],len,dep[maxn],Log[maxn],rmq[maxn][20],lr=0,idr[maxn]; 24 void dfs(int x,int fa) 25 { 26 list[++len]=x; A[x]=len; dep[x]=dep[fa]+1; rmq[++lr][0]=x; idr[x]=lr; 27 for (int i=first[x];i;i=edge[i].next) 28 { 29 Edge &e=edge[i]; if (e.to==fa) continue; 30 dfs(e.to,x); rmq[++lr][0]=x; 31 } 32 list[++len]=x; B[x]=len; 33 } 34 void makermq() 35 { 36 Log[0]=-1; for (int i=1;i<=lr;i++) Log[i]=Log[i>>1]+1; 37 for (int j=1;j<=18;j++) 38 for (int i=1,to=lr-(1<<j)+1;i<=to;i++) 39 rmq[i][j]=dep[rmq[i][j-1]]<dep[rmq[i+(1<<(j-1))][j-1]]?rmq[i][j-1]:rmq[i+(1<<(j-1))][j-1]; 40 } 41 int lca(int x,int y) 42 { 43 if (idr[x]>idr[y]) x^=y^=x^=y; x=idr[x]; y=idr[y]; 44 int l=Log[y-x+1]; 45 return dep[rmq[x][l]]<dep[rmq[y-(1<<l)+1][l]]?rmq[x][l]:rmq[y-(1<<l)+1][l]; 46 } 47 48 #define LL long long 49 LL ans[maxn],ss; bool have[maxn]; 50 void modify(int x) 51 { 52 if (have[list[x]]) ss-=V[a[list[x]]]*1ll*W[cnt[a[list[x]]]],cnt[a[list[x]]]--; 53 else cnt[a[list[x]]]++,ss+=V[a[list[x]]]*1ll*W[cnt[a[list[x]]]]; 54 have[list[x]]^=1; 55 } 56 void timemodify(int L,int R,int x,int v) 57 { 58 if ((L<=A[x] && A[x]<=R)^(L<=B[x] && B[x]<=R)) modify(A[x]),a[x]=v,modify(A[x]); 59 else a[x]=v; 60 } 61 62 int main() 63 { 64 scanf("%d%d%d",&n,&m,&lq); 65 bl=2185; 66 for (int i=1;i<=n*2;i++) bel[i]=(i-1)/bl+1; tot=bel[n*2]; 67 for (int i=1;i<=m;i++) scanf("%d",&V[i]); 68 for (int i=1;i<=n;i++) scanf("%d",&W[i]); 69 for (int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),insert(x,y); 70 for (int i=1;i<=n;i++) scanf("%d",&a[i]); 71 dfs(1,0); makermq(); 72 lc=0; 73 for (int i=1,op,j=0;i<=lq;i++) 74 { 75 scanf("%d",&op); 76 if (op==1) 77 { 78 j++; scanf("%d%d",&q[j].l,&q[q[j].id=j].r); q[j].t=lc; 79 int l=lca(q[j].l,q[j].r); 80 if (l==q[j].l || l==q[j].r) {int t=q[j].l; q[j].l=min(A[t],A[q[j].r]); q[j].r=max(A[t],A[q[j].r]); q[j].biu=0;} 81 else 82 { 83 if (A[q[j].l]<A[q[j].r]) q[j].l=B[q[j].l],q[j].r=A[q[j].r]; 84 else {int t=q[j].l; q[j].l=B[q[j].r]; q[j].r=A[t];} 85 q[j].biu=A[l]; 86 } 87 } 88 else 89 { 90 lc++; scanf("%d%d",&mo[lc].x,&mo[lc].b); 91 mo[lc].a=a[mo[lc].x]; a[mo[lc].x]=mo[lc].b; 92 } 93 } 94 lq-=lc; 95 sort(q+1,q+1+lq,cmp); 96 97 int L=1,R=0,T=lc; ss=0; 98 for (int i=1;i<=lq;i++) 99 { 100 while (T<q[i].t) T++,timemodify(L,R,mo[T].x,mo[T].b); 101 while (T>q[i].t) timemodify(L,R,mo[T].x,mo[T].a),T--; 102 while (L<q[i].l) modify(L),L++; 103 while (L>q[i].l) L--,modify(L); 104 while (R<q[i].r) R++,modify(R); 105 while (R>q[i].r) modify(R),R--; 106 if (q[i].biu) modify(q[i].biu); 107 ans[q[i].id]=ss; 108 if (q[i].biu) modify(q[i].biu); 109 } 110 for (int i=1;i<=lq;i++) printf("%lld\n",ans[i]); 111 return 0; 112 }