• BZOJ 4034 树上操作


    熟练剖分

    不想写树剖怎么办QwQ
    维护每个点(Ans)
    操作(1)就是子树加
    操作(2)是操作(1)的叠加......
    认真分析......
    子树加(dep)!!!

    写个树状数组节省一下码量
    (节省了还是100+)
    (我选择死亡)

    #include <cstdio>
    
    const int MAXN=100111;
    
    int N, M;
    int X;
    long long op;
    long long Ans;
    
    struct Vert{
    	int FE;
    	int Dps, Dpr;
    	int Dep;
    	long long Val, Sum;
    } V[MAXN];
    
    struct Edge{
    	int x, y, next;
    } E[MAXN<<1];
    
    int Ecnt;
    
    void addE(int a, int b){
    	++Ecnt;
    	E[Ecnt].x=a;E[Ecnt].y=b;E[Ecnt].next=V[a].FE;V[a].FE=Ecnt;
    }
    
    int Dfn[MAXN], DFN;
    
    void DFS(int at, int f=0){
    	++DFN;
    	Dfn[DFN]=at;
    	V[at].Dps=DFN;
    	for(int k=V[at].FE, to;k>0;k=E[k].next){
    		to=E[k].y;
    		if(to==f)	continue;
    		V[to].Dep=V[at].Dep+1;
    		V[to].Sum=V[at].Sum+V[to].Val;
    		DFS(to, at);
    	}
    	V[at].Dpr=DFN;
    }
    
    int lowbit(int a){
    	return a&(-a);
    }
    
    struct Trray{
    	int L;
    	long long n[MAXN];
    	void init(int l){
    		L=l;
    		for(int i=0;i<MAXN;++i)	n[i]=0LL;
    	}
    	long long Ask(int p){
    		long long ret=0LL;
    		for(int i=p;i>0;i-=lowbit(i))
    			ret+=n[i];
    		return ret;
    	}
    	void Update(int l, int r, long long d){
    		for(int i=l;i<=L;i+=lowbit(i))		n[i]+=d;
    		for(int i=r+1;i<=L;i+=lowbit(i))	n[i]-=d;
    	}
    } Cv, Cd;
    
    int main(){
    	
    	scanf("%d%d", &N, &M);
    	
    	for(int i=1;i<=N;++i)	scanf("%lld", &V[i].Val);
    	
    	for(int i=1, a, b;i<N;++i){
    		scanf("%d%d", &a, &b);
    		addE(a, b);addE(b, a);
    	}
    	
    	V[1].Dep=1;
    	V[1].Sum=V[1].Val;
    	DFS(1);
    	
    	Cv.init(DFN);Cd.init(DFN);
    	
    	for(int t;M--;){
    		scanf("%d", &t);
    		if(t==1){
    			scanf("%d%lld", &X, &op);
    			Cv.Update(V[X].Dps, V[X].Dpr, op);
    		}
    		if(t==2){
    			scanf("%d%lld", &X, &op);
    			Cd.Update(V[X].Dps, V[X].Dpr, op);
    			Cv.Update(V[X].Dps, V[X].Dpr, -op*(long long)(V[X].Dep-1));
    		}
    		if(t==3){
    			scanf("%d", &X);
    			Ans=V[X].Sum;
    			Ans+=Cv.Ask(V[X].Dps);
    			Ans+=Cd.Ask(V[X].Dps)*(long long)(V[X].Dep);
    			printf("%lld
    ", Ans);
    		}
    	}
    	
    	return 0;
    }
    
    /*
    5 5
    1 2 3 4 5
    1 2
    1 4
    2 3
    2 5
    3 3
    1 2 1
    3 5
    2 1 2
    3 3
    
    6
    9
    13
    
    */
    
    
  • 相关阅读:
    CF1305 Ozon Tech Challenge 2020 游戏存档
    CF1310A Recommendations 题解
    CF755G PolandBall and Many Other Balls 题解
    关于后缀自动机
    具体数学学习笔记
    Flask-SQLAlchemy中解决1366报错
    常用的SQLalchemy 字段类型
    flask_model防止循环引用
    navicate远程访问ubuntu上的mysql数据库
    flask运行环境搭建(nginx+gunicorn)
  • 原文地址:https://www.cnblogs.com/Pickupwin/p/9545222.html
Copyright © 2020-2023  润新知