zoukankan      html  css  js  c++  java
  • [BZOJ3730]震波

    description

    题面

    solution

    动态点分治第三题。

    动态维护与某点距离(le k)的所有点的点权和.

    对于每一个节点开两棵线段树:一棵维护以距离为下标的点权和,
    一棵维护对父亲的贡献。

    没写过线段树动态开点...
    于是就改成了树状数组...

    code

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<fstream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<clocale>
    #include<cctype>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<list>
    #include<map>
    #include<set>
    #define FILE "a"
    #define mp make_pair
    #define pb push_back
    #define RG register
    #define il inline
    #define RAND
    using namespace std;
    typedef unsigned long long ull;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const int inf=2147483647;
    const dd pi=acos(-1);
    const dd eps=1e-10;
    const int mod=1e9+7;
    const int N=100010;
    const ll INF=1e18+1;
    il ll read(){
    	RG ll data=0,w=1;RG char ch=getchar();
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
    	return data*w;
    }
    il int make(int l,int r){return rand()%(r-l+1)+l;}
    il void file(){	
    	freopen(FILE".in","r",stdin);
    	freopen(FILE".out","w",stdout);
    }
    /*********************************************************************/
    
    int n,m,val[N];
    int head[N],nxt[N<<1],to[N<<1],cnt;
    il void add(int u,int v){
    	to[++cnt]=v;
    	nxt[cnt]=head[u];
    	head[u]=cnt;
    }
    int pa[N],siz[N],deb[N],top[N],son[N];
    void dfs1(int u,int ff){
    	siz[u]=1;pa[u]=ff;son[u]=0;deb[u]=deb[ff]+1;
    	for(RG int i=head[u];i;i=nxt[i]){
    		RG int v=to[i];if(v==ff)continue;
    		dfs1(v,u);siz[u]+=siz[v];
    		if(!son[u]||siz[son[u]]<siz[v])son[u]=v;
    	}
    }
    void dfs2(int u,int tp){
    	top[u]=tp;if(son[u])dfs2(son[u],tp);
    	for(RG int i=head[u];i;i=nxt[i]){
    		RG int v=to[i];if(v==pa[u]||v==son[u])continue;
    		dfs2(v,v);
    	}
    }
    il int lca(int u,int v){
    	while(top[u]!=top[v]){
    		if(deb[top[u]]<deb[top[v]])swap(u,v);
    		u=pa[top[u]];
    	}
    	return deb[u]<deb[v]?u:v;
    }
    il int dist(int u,int v){return deb[u]+deb[v]-2*deb[lca(u,v)];}
    /*********************************************************************/
    
    int RT,rt,block,sz[N],w[N],fa[N],dep[N];bool vis[N];
    #define lowbit(x) ((x)&(-(x)))
    struct BIT{
    	vector<int> ret;
    	il int maxdep(){return ret.size()-1;}
    	il void insert(int D,int v){
    		RG int len=ret.size();while(len-1<D){ret.pb(0);len++;}
    		for(D;D<len;D=(D+1)+lowbit(D+1)-1)ret[D]+=v;
    	}
    	il int query(int k){
    		RG int s=0,len=ret.size();
    		for(k;~k;k=(k+1)-lowbit(k+1)-1)s+=ret[k];return s;
    	}
    }sum[N],tofa[N];
    void getsmd(int u,int ff,int nw){
    	dep[u]=dep[ff]+1;sum[nw].insert(dep[u]-1,0);
    	for(RG int i=head[u];i;i=nxt[i]){
    		RG int v=to[i];if(v==ff||vis[v])continue;
    		getsmd(v,u,nw);
    	}
    }
    void getsum(int u,int ff,int nw){
    	dep[u]=dep[ff]+1;sum[nw].insert(dep[u]-1,val[u]);
    	for(RG int i=head[u];i;i=nxt[i]){
    		RG int v=to[i];if(v==ff||vis[v])continue;
    		getsum(v,u,nw);
    	}
    }
    void gettmd(int u,int ff,int nw){
    	dep[u]=dep[ff]+1;tofa[nw].insert(dep[u],0);
    	for(RG int i=head[u];i;i=nxt[i]){
    		RG int v=to[i];if(v==ff||vis[v])continue;
    		gettmd(v,u,nw);
    	}	
    }
    void gettofa(int u,int ff,int nw){
    	dep[u]=dep[ff]+1;tofa[nw].insert(dep[u],val[u]);
    	for(RG int i=head[u];i;i=nxt[i]){
    		RG int v=to[i];if(v==ff||vis[v])continue;
    		gettofa(v,u,nw);
    	}
    }
    void getrt(int u,int ff){
    	sz[u]=1;w[u]=0;
    	for(RG int i=head[u];i;i=nxt[i]){
    		RG int v=to[i];if(v==ff||vis[v])continue;
    		getrt(v,u);sz[u]+=sz[v];
    		w[u]=max(w[u],sz[v]);
    	}
    	w[u]=max(w[u],block-sz[u]);if(w[rt]>w[u])rt=u;
    }
    void solve(int u,int ff){
    	getsmd(u,0,u);getsum(u,0,u);fa[u]=ff;vis[u]=1;
    	for(RG int i=head[u];i;i=nxt[i]){
    		RG int v=to[i];if(v==ff||vis[v])continue;
    		block=sz[v];rt=0;
    		getrt(v,0);gettmd(v,0,rt);gettofa(v,0,rt);solve(rt,u);
    	}
    }
    /*********************************************************************/
    
    il void Mod(int x,int y){
    	y=y-val[x];val[x]+=y;RG int d=0;sum[x].insert(d,y);
    	for(RG int u=x;fa[u];u=fa[u])
    		d=dist(x,fa[u]),tofa[u].insert(d,y),sum[fa[u]].insert(d,y);
    }
    il int Qry(int x,int k){
    	RG int D,s=sum[x].query(min(k,sum[x].maxdep()));
    	for(RG int u=x;fa[u];u=fa[u]){
    		D=dist(x,fa[u]);if(k<D)continue;
    		s-=tofa[u].query(min(k-D,tofa[u].maxdep()));
    		s+=sum[fa[u]].query(min(k-D,sum[fa[u]].maxdep()));
    	}
    	return s;
    }
    /*********************************************************************/
    
    int ans;
    int main()
    {
    	n=read();m=read();
    	for(RG int i=1;i<=n;i++)val[i]=read();
    	for(RG int i=1,u,v;i<n;i++)u=read(),v=read(),add(u,v),add(v,u);		
    	dfs1(1,0);dfs2(1,1);w[0]=block=n;RT=rt=0;getrt(1,0);solve(rt,0);
    	for(RG int i=1,o,x,y;i<=m;i++){
    		o=read();x=read()^ans;y=read()^ans;
    		o?Mod(x,y),0:printf("%d
    ",ans=Qry(x,y));
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    经典面试题(二)附答案 算法+数据结构+代码 微软Microsoft、谷歌Google、百度、腾讯
    ctype.h库函数
    结构体大小与内存对齐问题
    整数v,从高位到低位,取c位数,得到最大数 (其中:v>=10^c)
    32位与64 位下各类型长度对比
    C++容器类
    笔试题 相对位置不变的正负数排序
    composer 下载安装
    nginx 多进程 + io多路复用 实现高并发
    go 成长路上的坑(1)
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9427226.html
Copyright © 2011-2022 走看看