樹鏈剖分題目
阿新 • • 發佈:2018-11-28
#include<bits/stdc++.h> #define lowbit(x) (x&(-(x))) #define lson rt<<1 #define rson rt<<1|1 #define mme(a,b) memset((a),(b),sizeof((a))) #define fuck(x) cout<<"* "<<x<<"\n" #define iis std::ios::sync_with_stdio(false) #define fi first #define se second using namespace std; typedef long long LL; const int INF = 0x3f3f3f3f; const int MOD = 998244353; const int N = 1e5 + 7; const int MX = 2e5 + 7; int n, m, q, mod, root; struct Tree{ int l,r,d,Sum,lazy; }sgt[N<<2]; int ar[N]; struct lp{ int v,nex; }cw[MX]; int head[MX],tot; int inde; int sz[MX],top[MX],son[MX],dep[MX],faz[MX]; int tid[MX],rnk[MX],rtid[MX];//id->dfsid//dfsid->id//lastid void init(){ tot=-1;inde=0; mme(head,-1);mme(son,-1); mme(sz,0);mme(dep,0);mme(faz,0);mme(top,0); mme(tid,0);mme(rtid,0);mme(rnk,0); } void push_up(int rt){ sgt[rt].Sum=(sgt[lson].Sum+sgt[rson].Sum)%mod; } void push_down(int rt){ if(sgt[rt].lazy){ int c = sgt[rt].lazy; sgt[lson].lazy=(sgt[lson].lazy+sgt[rt].lazy)%mod; sgt[rson].lazy=(sgt[rson].lazy+sgt[rt].lazy)%mod; sgt[lson].Sum=(sgt[lson].Sum+sgt[lson].d*c%mod)%mod; sgt[rson].Sum=(sgt[rson].Sum+sgt[rson].d*c%mod)%mod; sgt[rt].lazy=0; } } void build(int l,int r,int rt){ sgt[rt].l=l;sgt[rt].r=r; sgt[rt].d=r-l+1; sgt[rt].lazy=0; if(l==r){ sgt[rt].Sum=ar[rnk[l]]; return; } int mid=(l+r)>>1; build(l,mid,lson);build(mid+1,r,rson); push_up(rt); } void update(int L,int R,int c,int rt){ int l = sgt[rt].l,r=sgt[rt].r,mid=(l+r)>>1; if(sgt[rt].l>R||sgt[rt].r<L)return; if(L<=l&&r<=R){ sgt[rt].lazy=(c+sgt[rt].lazy)%mod; sgt[rt].Sum=(sgt[rt].Sum+sgt[rt].d*c%mod)%mod; return; } if(sgt[rt].l==sgt[rt].r)return; push_down(rt); if(L<=mid)update(L,R,c,lson); if(R>mid)update(L,R,c,rson); push_up(rt); } int query(int L,int R,int rt){ int l = sgt[rt].l,r=sgt[rt].r,mid=(l+r)>>1; if(L<=l&&r<=R){ return sgt[rt].Sum; } if(sgt[rt].l>R||sgt[rt].r<L)return 0; if(sgt[rt].l==sgt[rt].r)return 0; push_down(rt); int _sum = 0; if(L<=mid)_sum = query(L,R,lson)%mod; if(R>mid)_sum=(_sum+query(L,R,rson))%mod; return _sum; } void dfs1(int u,int fat,int depth){ dep[u] = depth;faz[u] = fat;sz[u] = 1; son[u] = 0; for(int i=head[u];~i;i=cw[i].nex){ int v = cw[i].v; if(v==fat)continue; dfs1(v,u,depth+1); sz[u] += sz[v]; if(sz[v]>sz[son[u]]){ son[u] = v; } } } void dfs2(int u,int t){ tid[u] = ++inde; rnk[inde]=u; if(son[u]){ top[son[u]] = top[u]; dfs2(son[u],u); } for(int i=head[u];~i;i=cw[i].nex){ int v = cw[i].v; if(v!=son[u]&&v!=faz[u]){ top[v]=v; dfs2(v,u); } } rtid[u]=inde; } int path_query(int x,int y){ int ans=0; int fx=top[x],fy=top[y]; while(fx!=fy){ if(dep[fx]>=dep[fy]){ ans=(ans+query(tid[fx],tid[x],1))%mod; x=faz[fx]; }else { ans=(ans+query(tid[fy],tid[y],1))%mod; y=faz[fy]; } fx=top[x],fy=top[y]; } if(tid[x]<tid[y]){ ans=(ans+query(tid[x],tid[y],1))%mod; }else { ans=(ans+query(tid[y],tid[x],1))%mod; } return ans; } void path_update(int x,int y,int c){ int fx=top[x],fy=top[y]; while(fx!=fy){ if(dep[fx]>dep[fy]){ update(tid[fx],tid[x],c,1); x=faz[fx]; }else { update(tid[fy],tid[y],c,1); y=faz[fy]; } fx=top[x],fy=top[y]; } if(tid[x]<tid[y]){ update(tid[x],tid[y],c,1); }else { update(tid[y],tid[x],c,1); } } void add_edge(int u,int v){ cw[++tot].v=v;cw[tot].nex=head[u]; head[u]=tot; cw[++tot].v=u;cw[tot].nex=head[v]; head[v]=tot; } void pre_build(){ dfs1(root,root,1); top[root]=root; dfs2(root,root); build(1,n,1); } int main(){ while(~scanf("%d%d%d%d",&n,&q,&root,&mod)){ init(); for(int i=1;i<=n;++i){ scanf("%d",&ar[i]); ar[i]%=mod; } for(int i=1,u,v;i<n;++i){ scanf("%d%d",&u,&v); add_edge(u,v); } pre_build(); while(q--){ int op;scanf("%d",&op); int u,v,w; if(op==1){ scanf("%d%d%d",&u,&v,&w); w%=mod; path_update(u,v,w); }else if(op==2){ scanf("%d%d",&u,&v); printf("%d\n", path_query(u,v)); }else if(op==3){ scanf("%d%d",&u,&w); w%=mod; update(tid[u],rtid[u],w,1); }else if(op==4){ scanf("%d",&u); printf("%d\n", query(tid[u],rtid[u],1)); } } } return 0; }
#include<bits/stdc++.h> #define lson rt<<1 #define rson rt<<1|1 #define fi first #define se second #define mme(a,b) memset((a),(b),sizeof((a))) #define iis std::ios::sync_with_stdio(false) #define Mod(a, b) a<b?a:a%b+b using namespace std; typedef long long LL; const int MXN = 2e5 + 7; const int mod = 1000000007; const int INF = 0x3f3f3f3f; int n, m, k; struct one{ int u, v, c; }opt[MXN]; std::vector<int> mp[MXN]; int fa[MXN], dep[MXN], son[MXN], top[MXN], tid[MXN], rtid[MXN], siz[MXN]; int inde; int rnk[MXN]; int sum[MXN<<2], flag[MXN<<2]; int ans[MXN], res[MXN<<2]; void build(int l,int r,int rt) { sum[rt] = 0; flag[rt] = 0; if(l == r) return; int mid = (l + r) >> 1; build(l,mid,lson), build(mid+1,r,rson); } void push_up(int rt) { if(sum[lson] < k && sum[rson] < k) { sum[rt] = max(sum[lson], sum[rson]); } } void push_down(int rt) { flag[lson] += flag[rt]; flag[rson] += flag[rt]; sum[lson] += flag[rt]; sum[rson] += flag[rt]; flag[rt] = 0; } void fuck(int c,int l,int r,int rt) { if(sum[rt] != k) return; if(l == r) { ans[rnk[l]] = c; sum[rt] = -INF; return; } push_down(rt); int mid = (l + r) >> 1; fuck(c, l, mid, lson); fuck(c, mid + 1, r, rson); push_up(rt); } void updata(int L,int R,int c,int l,int r,int rt) { if(L <= l && r <= R) { ++ flag[rt]; ++ sum[rt]; fuck(c, l, r, rt); return; } push_down(rt); int mid = (l + r) >> 1; if(L > mid) updata(L,R,c,mid+1,r,rson); else if(R <= mid) updata(L,R,c,l,mid,lson); else { updata(L,mid,c,l,mid,lson); updata(mid+1,R,c,mid+1,r,rson); } push_up(rt); } void dfs_1(int u,int ba,int D) { fa[u] = ba; dep[u] = D; son[u] = 0; siz[u] = 1; for(auto v: mp[u]) { if(v == ba) continue; dfs_1(v, u, D+1); siz[u] += siz[v]; if(siz[v] > siz[son[u]]) son[u] = v; } } void dfs_2(int u,int ba) { tid[u] = ++inde; rnk[inde] = u; if(son[u]) { top[son[u]] = top[u]; dfs_2(son[u], u); } for(auto v: mp[u]) { if(v == ba || v == son[u]) continue; top[v] = v; dfs_2(v, u); } rtid[u] = inde; } void updata_path(int x,int y,int c) { int fx = top[x], fy = top[y]; while(fx != fy) { if(dep[fx] <= dep[fy]) swap(fx,fy),swap(x,y); updata(tid[fx], tid[x], c, 1, n, 1); x = fa[fx]; fx = top[x], fy = top[y]; } if(tid[x] >= tid[y]) swap(x, y); updata(tid[x], tid[y], c, 1, n, 1); } int main() { scanf("%d%d%d", &n, &m, &k); for(int i = 1, a, b; i < n; ++i) { scanf("%d%d", &a, &b); mp[a].push_back(b); mp[b].push_back(a); } for(int i = 0, u, v, c; i < m; ++i) { scanf("%d%d%d", &opt[i].u, &opt[i].v, &opt[i].c); } dfs_1(1, 1, 1); top[1] = 1; dfs_2(1, 1); build(1, n, 1); for(int i = m-1; i >= 0; --i) { updata_path(opt[i].u,opt[i].v,opt[i].c); } for(int i = 1; i < n; ++i) { printf("%d ", ans[i]); } printf("%d\n", ans[n]); return 0; }