树链剖分题目

P3384[模板]树链剖分

#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;
}


牛客国庆集训派对Day6-I-清明梦超能力者黄YY

#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;
}

猜你喜欢

转载自www.cnblogs.com/Cwolf9/p/10032049.html