ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

转存

2022-06-18 12:33:28  阅读:134  来源: 互联网

标签:rt lazy int rson fa now 转存


#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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有