其他分享
首页 > 其他分享> > 转存

转存

作者:互联网

#include <bits/stdc++.h>
#define endl putchar('\n')
#define lson(x) tree[x].ch[0]
#define rson(x) tree[x].ch[1]
#define siz(x) tree[x].size
#define fa(x) tree[x].fa
#define lazy(rt) tree[rt].lazy
#define sum(x) tree[x].sum
#define val(x) tree[x].val
#define flag printf("----------\n");
using namespace std;
const int M =1e6+10;
const int inf = 2147483647;
struct Splay{
    int ch[2];
    int val,fa,cnt,size,lazy,sum;
};
Splay tree[M];int root,tot;
int tag[M];
inline int read(){
    int x=0,f=0;char c=getchar();
    while(!isdigit(c)){
        if(c=='-') f=1;c=getchar();
    }
    do{
        x=(x<<1)+(x<<3)+(c^48);
    }while(isdigit(c=getchar()));
    return f?-x:x;
}
inline void print(int x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) print(x/10);putchar(x%10^48);
}
void update(int rt){
    siz(rt)=siz(lson(rt))+siz(rson(rt))+1;//!!
    sum(rt)=sum(lson(rt))+sum(rson(rt))+val(rt);
}
void pushdown(int rt){
    if(lazy(rt)){
        if(lson(rt)){
            sum(lson(rt))+=lazy(rt)*siz(lson(rt));
            val(lson(rt))+=tag[lson(rt)]*lazy(rt);
            lazy(lson(rt))+=lazy(rt);
        }
        if(rson(rt)){
            sum(rson(rt))+=lazy(rt)*siz(rson(rt));
            val(rson(rt))+=tag[rson(rt)]*lazy(rt);
            lazy(rson(rt))+=lazy(rt);
        }
    }
}
bool which(int rt){
    return (rson(fa(rt))==rt);
}
void link(int rt,int fa,int op){
    tree[fa].ch[op]=rt;
    fa(rt)=fa;
}
void twist(int rt){
    int fa=fa(rt),grand=fa(fa);
    int op1=which(rt),op2=which(fa);
    pushdown(fa);pushdown(rt);
    link(rt,grand,op2);
    link(tree[rt].ch[op1^1],fa,op1);
    link(fa,rt,(op1^1));
    update(fa);update(rt);
}
void splay(int rt,int to){
    while(fa(rt)!=to){
        if(fa(fa(rt))!=to) twist((which(rt)==which(fa(rt)))?fa(rt):rt);
        twist(rt);
    }
    if(!to) root=rt;
}
int dfn[M],a[M],n,tim=1;
vector <int> vec[M];
void dfs(int u){
    dfn[++tim]=u;
    for(int i=0;i<vec[u].size();i++) dfs(vec[u][i]);
    dfn[++tim]=u+n;
}
int build(int l,int r,int fa){
    if(l>r) return 0;
    int mid=(l+r)>>1,now=dfn[mid];//二分建完美树 
    fa(now)=fa;
    lson(now)=build(l,mid-1,now);
    rson(now)=build(mid+1,r,now);
    val(now)=(now<=n)?a[now]:-a[now];
    update(now);
    return now;
}
int pre(int x){
    splay(x,0);
    int now=lson(x);
    while(rson(now)) now=rson(now);
    return now;
}
int down(int x){
    splay(x,0);
    int now=rson(x);
    while(lson(x)) now=lson(x);
    return now;
}
void change(int x,int y){//change x to y
    int p=pre(x),q=down(x+n);
    splay(p,0);splay(q,p);
    int o=lson(q);
    fa(lson(q))=0;lson(q)=0;
    update(rson(root));update(root);
    q=down(y);
    splay(y,0);splay(q,y);
    fa(o)=q;lson(q)=o;
    update(rson(root));update(root);
}
int asksum(int x){
    int p=n*2+1,q=down(x);
    splay(p,0);splay(q,p);
    return sum(lson(q));
}
void add(int x,int y){
    int p=pre(x),q=down(x+n);
    splay(p,0);splay(q,p);
    lazy(lson(q))+=y;
    sum(lson(q))+=y*siz(lson(q));
    val(lson(q))+=tag[lson(q)]*y;
}
int main(){
       n=read();
       for(int i=2;i<=n;i++){
           int x=read();
        vec[x].push_back(i);    
    }
    for(int i=1;i<=n;i++){
        a[i]=read();tag[i]=1,tag[i+n]=-1;
    }
    dfn[1]=n*2+1;
    dfs(1);
    dfn[++tim]=n*2+2;
    root=build(1,tim,0);
    int t=read();
    while(t--){
        char op=getchar();while(!isalpha(op)) op=getchar();
        int x,y;
        if(op=='Q') x=read(),print(asksum(x)),endl;
        if(op=='C') x=read(),y=read(),change(x,y);
        if(op=='F') x=read(),y=read(),add(x,y);
    }
    return 0;
}
/*
#include<iostream>
#include<cstring>
#include<cstdio>
#define N (200009)
#define LL long long
using namespace std;

struct Edge{int to,next;}edge[N<<1];
int n,m,x,y,Root,q[N],q_num;
int head[N],num_edge;
int Son[N][2],Father[N];
int a[N],Flag[N];
LL Num[N],Sum[N],Val[N],Add[N];
char opt;

inline int read()
{
    int x=0; char c=getchar();
    while (c<'0' || c>'9') c=getchar();
    while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
    return x;
}

void add(int u,int v)
{
    edge[++num_edge].to=v;
    edge[num_edge].next=head[u];
    head[u]=num_edge;
}

int Get(int x) {return Son[Father[x]][1]==x;}

void Pushup(int x)
{
    Num[x]=Num[Son[x][0]]+Num[Son[x][1]]+Flag[x];
    Sum[x]=Sum[Son[x][0]]+Sum[Son[x][1]]+Val[x];
}

void Pushdown(int x)
{
    if (Add[x])
    {
        int ls=Son[x][0], rs=Son[x][1];
        Sum[ls]+=Add[x]*Num[ls];
        Val[ls]+=Flag[ls]*Add[x]; Add[ls]+=Add[x];
        Sum[rs]+=Add[x]*Num[rs];
        Val[rs]+=Flag[rs]*Add[x]; Add[rs]+=Add[x];
        Add[x]=0;
    }
}

void Rotate(int x)
{
    int wh=Get(x);
    int fa=Father[x],fafa=Father[fa];
    Pushdown(fa); Pushdown(x);
    if (fafa) Son[fafa][Son[fafa][1]==fa]=x;
    Son[fa][wh]=Son[x][wh^1]; Father[fa]=x;
    if (Son[fa][wh]) Father[Son[fa][wh]]=fa;
    Son[x][wh^1]=fa; Father[x]=fafa;
    Pushup(fa); Pushup(x);
}

void Splay(int x,int tar)
{
    for (int fa; (fa=Father[x])!=tar; Rotate(x))
        if (Father[fa]!=tar)
            Rotate(Get(fa)==Get(x)?fa:x);
    if (!tar) Root=x;
}

int Pre(int x)
{
    Splay(x,0);
    int now=Son[x][0];
    while (Son[now][1]) now=Son[now][1];
    return now;
}

int Next(int x)
{
    Splay(x,0);
    int now=Son[x][1];
    while (Son[now][0]) now=Son[now][0];
    return now;
}

void Query(int x)
{
    int pre=n<<1|1, nxt=Next(x);
    Splay(pre,0);
    Splay(nxt,pre);
    printf("%lld\n",Sum[Son[nxt][0]]);
}

void Change(int x,int y)
{
    int pre=Pre(x),nxt=Next(x+n);
    Splay(pre,0); Splay(nxt,pre);
    int tmp=Son[nxt][0];
    Father[Son[nxt][0]]=0; Son[nxt][0]=0;
    Pushup(Son[Root][1]); Pushup(Root);

    int Nxt=Next(y);
    Splay(y,0); Splay(Nxt,y);
    Father[tmp]=Nxt; Son[Nxt][0]=tmp;
    Pushup(Son[Root][0]); Pushup(Root);
}

void Update(int x,int y)
{
    int pre=Pre(x), nxt=Next(x+n);
    Splay(pre,0); Splay(nxt,pre);
    int tmp=Son[nxt][0];
    Add[tmp]+=y;
    Sum[tmp]+=Add[tmp]*Num[tmp];
    Val[tmp]+=Flag[tmp]*Add[tmp];
}

void DFS(int x,int fa)
{
    q[++q_num]=x;
    for (int i=head[x]; i; i=edge[i].next)
        if (edge[i].to!=fa) DFS(edge[i].to,x);
    q[++q_num]=x+n;
}

int Build(int l,int r,int fa)
{
    if (l>r) {return 0;}
    int mid=(l+r)>>1, now=q[mid];
    Father[now]=fa;
    Son[now][0]=Build(l,mid-1,now);
    Son[now][1]=Build(mid+1,r,now);
    Val[now]=(now<=n)?a[now]:-a[now-n];
    Pushup(now); return now;
}

int main()
{
    n=read();
    for (int i=2; i<=n; ++i)
        x=read(), add(x,i);
    for (int i=1; i<=n; ++i)
        a[i]=read(), Flag[i]=1, Flag[i+n]=-1;
    q[q_num=1]=n<<1|1;
    DFS(1,0);
    q[++q_num]=n+1<<1;
    Root=Build(1,q_num,0);
    m=read();
    for (int i=1; i<=m; ++i)
    {
        opt=getchar(); while (opt<'A' || opt>'Z') opt=getchar();
        if (opt=='Q') x=read(), Query(x);
        if (opt=='C') x=read(), y=read(), Change(x,y);
        if (opt=='F') x=read(), y=read(), Update(x,y);
    }
}
*/

 

标签:rt,lazy,int,rson,fa,now,转存
来源: https://www.cnblogs.com/blue-tsg/p/16388090.html