树剖裸题,0pts 求调
查看原帖
树剖裸题,0pts 求调
515129
TLEWA楼主2022/11/22 09:55

rt,呜呜呜

#include<bits/stdc++.h>
using namespace std;

const int N=100050,M=200050;
int n,m,r;
int fa[N],size[N],dep[N],son[N],dfn[N],top[N];
int val[N];

struct Node {
    int to,next;
}arr[M]; 
int first[N],p;

void add(int u,int v) {
    arr[++p].to=v;
    arr[p].next=first[u];
    first[u]=p;
}

struct Tree {
    int l,r;
    long long add,sum;
}tre[N*4];

inline int ls(int p){return p<<1;}
inline int rs(int p){return p<<1|1;}

void pushup(int u) {tre[u].sum=(tre[ls(u)].sum+tre[rs(u)].sum);}
void pushdown(int u) {
    auto &root=tre[u],&lson=tre[ls(u)],&rson=tre[rs(u)];
    if(root.add) {
        lson.add+=root.add,lson.sum+=root.add*(lson.r-lson.l+1);
        rson.add+=root.add,rson.sum+=root.add*(rson.r-rson.l+1);
        root.add=0;
    }
//  cout << "123123fsdfs" << endl;
}

void build(int u,int l,int r) {
    tre[u].l=l,tre[u].r=r,tre[u].add=0,tre[u].sum=0;
    if(l==r) return;
    int mid=(l+r)/2;
    build(ls(u),l,mid);
    build(rs(u),mid+1,r);
}

void plu(int u,int l,int r,int k) {
    if(l<=tre[u].l&&r>=tre[u].r) tre[u].add=k,tre[u].sum=k*(tre[u].r-tre[u].l+1);
    else {
        pushdown(u);
        int mid=(tre[u].l+tre[u].r)/2;
        if(l<=mid) plu(ls(u),l,r,k);
        if(mid<r) plu(rs(u),l,r,k);
        pushup(u);
    }
}

long long query(int u,int l,int r) {
    if(l<=tre[u].l&&r>=tre[u].r) return tre[u].sum;
    pushdown(u);
    int mid=(tre[u].l+tre[u].r)/2;
    long long summ=0;
    if(l<=mid) summ+=query(ls(u),l,r);
    if(mid<r) summ+=query(rs(u),l,r);
    return summ;
}

void dfs1(int u,int f) {
//  if(u==0) return;
    fa[u]=f;
    size[u]=1;
    dep[u]=dep[f]+1;
    int mson=0;
    for(int i=first[u];i;i=arr[i].next) {
        if(arr[i].to==f) continue;
        dfs1(arr[i].to,u);
        size[u]+=size[arr[i].to];
        if (son[u]==0||size[son[u]]<size[arr[i].to]) son[u]=arr[i].to;
        else if (size[son[u]]==size[arr[i].to]&&son[u]>arr[i].to) son[u]=arr[i].to;
    }
}

int cnt;
void dfs2(int u,int f) {
    top[u]=f;
    dfn[u]=++cnt;
//  cout << "发NSF" << endl;
    if(son[u]==0) return;
    dfs2(son[u],f);
    for(int i=first[u];i;i=arr[i].next) {
        if(arr[i].to==son[u]||arr[i].to==fa[u]) continue;
        dfs2(arr[i].to,arr[i].to);
    }
}

void plus_path(int u,int v,int k) {
    while(top[u]!=top[v]) {
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        plu(1,dfn[top[u]],dfn[u],k);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v]) swap(u,v);
    plu(1,dfn[u],dfn[v],k);
}

long long query_path(int u,int v) {
    long long summ=0;
    while(top[u]!=top[v]) {
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        summ+=query(1,dfn[top[u]],dfn[u]);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v]) swap(u,v);
    summ+=query(1,dfn[u],dfn[v]);
    return summ;
}

void plus_tree(int u,int k) {
    plu(1,dfn[u],dfn[u]+size[u]-1,k);
}

long long query_tree(int u) {
    return query(1,dfn[u],dfn[u]+size[u]-1);
}

int main() {
    int n,x;
    cin >> n;
    for(int i=2;i<=n;++i) {
        cin >> x;
        add(x+1,i);
//        add(i,x+1);
    }
    build(1,1,n);
    dfs1(1,0); //遍历到的节点,该节点的父亲节点
//  cout << "热i法国火热" << endl;
    dfs2(1,1); //遍历到的节点,该节点所在链的顶点

	int m;
	cin >> m;
    string s;
    while(m--) {
        cin >> s;
        int a=query_tree(1);
//        cout << a << endl;
        if(s=="install") {
            cin >> x;
            x++;
            cout << "234@2343324324234的说法是v" << endl;
            plus_path(1,x,1);
            cout << abs(query_tree(1)-a) << endl;
        }else {
            cin >> x;
            x++;
//            cout << query_tree(x) << ' ' << a << endl;
            plus_tree(x,0);
            cout << abs(query_tree(1)-a) << endl;
        }
    }
    return 0;
}
2022/11/22 09:55
加载中...