40分求助
查看原帖
40分求助
448983
Mo20楼主2023/11/1 17:10

RT

#include<bits/stdc++.h>
using namespace std;
const int maxn=2000010;
inline int read()
{
    int x=0;int f=1;char c;
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
    return ~f?x:-x;
}
struct node{int to,nxt;}edge[maxn];
int head[maxn],tot_edge;int n,m;int a[maxn];
void add(int x,int y)
{   
    edge[++tot_edge].to=y;
    edge[tot_edge].nxt=head[x];
    head[x]=tot_edge;
}
struct BIT
{
	int siz;
	vector<int> bit;
	int lowbit(int x){return x&-x;}
	void build(int sz){for(int i=0;i<=sz+3;i++) bit.push_back(0);siz=sz+1;}
	void update(int x,int v){x++;for(;x<=siz;x+=lowbit(x)) bit[x]+=v;}
	int query(int x)
	{
		x++;x=min(x,siz);
		int res=0;
		for(;x;x-=lowbit(x)) res+=bit[x];
		return res;	
	}
}T1[maxn],T2[maxn];
namespace dfs_to_lca
{
    int dfn[maxn],dfn_cnt=0;int dep[maxn];
    int anc[maxn][21];
    int get(int x,int y){return dfn[x]<dfn[y]?x:y;}
    void dfs(int u,int fa)
    {
        anc[dfn[u]=++dfn_cnt][0]=fa;dep[u]=dep[fa]+1;
        for(int i=head[u];i;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(v==fa) continue;
            dfs(v,u);
        }
    }
    void pre_st()
    {
        for(int i=1;i<=__lg(n);i++)
            for(int j=1;j+(1<<i)-1<=n;j++)
                anc[j][i]=get(anc[j][i-1],anc[j+(1<<(i-1))][i-1]);
    }
    int lca(int x,int y)
    {
        if(x==y) return x;
        if((x=dfn[x])>(y=dfn[y]))x^=y^=x^=y;
        int d=__lg(y-x++);
        return get(anc[x][d],anc[y-(1<<d)+1][d]);
    }
    int dis(int x,int y){return dep[x]+dep[y]-2*dep[lca(x,y)];}
}
namespace divide_and_conquer_tree
{
    int vis[maxn],siz[maxn],fa_siz[maxn],fa_on_tree[maxn];
    int rt,heavy;
    void dfs1(int u,int fa)
    {
        siz[u]=1;
        for(int i=head[u];i;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(v==fa||vis[v]) continue;
            dfs1(v,u);
            siz[u]+=siz[v];
        }
    }
    void dfs2(int u,int fa)
    {
        fa_siz[u]=siz[rt]-siz[u];
        for(int i=head[u];i;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(v==fa||vis[v]) continue;
            fa_siz[u]=max(fa_siz[u],siz[v]);
            dfs2(v,u);
        }
        if(fa_siz[heavy]>fa_siz[u]) heavy=u;
    }
    void solve(int u,int fa)
    {
        rt=heavy=u;
        dfs1(u,u);dfs2(u,u);
        T1[heavy].build(siz[heavy]);
        T2[heavy].build(siz[heavy]);
        fa_on_tree[heavy]=fa;
        vis[heavy]=1;int tmp=heavy;
        for(int i=head[tmp];i;i=edge[i].nxt){int v=edge[i].to;if(!vis[v]) solve(v,tmp);}
    }
	void change(int u,int k)
	{
		for(int i=u;i;i=fa_on_tree[i]) T1[i].update(dfs_to_lca::dis(u,i),k); 
		for(int i=u;fa_on_tree[i];i=fa_on_tree[i]) T2[i].update(dfs_to_lca::dis(u,fa_on_tree[i]),k);	
	}
    int query(int x,int k)
    {
        int ans=0;
        ans+=T1[x].query(k);
        for(int i=x;fa_on_tree[i];i=fa_on_tree[i])
        {
        	int dis=dfs_to_lca::dis(x,fa_on_tree[i]);
        	if(k>=dis) ans+=T1[fa_on_tree[i]].query(k-dis)-T2[i].query(k-dis);
        }
        return ans;
    }
}
int main()
{	
    freopen("P6329_1.in","r",stdin);
    //freopen("P6329_user.out","w",stdout);
    n=read();m=read();
    time_t st,ed;st=clock();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1,x,y;i<n;i++){x=read();y=read();add(x,y);add(y,x);}
    divide_and_conquer_tree::solve(1,0);
    dfs_to_lca::dfs(1,0);dfs_to_lca::pre_st();	
	/*for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++) cout<<i<<' '<<j<<' '<<dfs_to_lca::dis(i,j)<<endl;*/
    for(int i=1;i<=n;i++) divide_and_conquer_tree::change(i,a[i]);
    int last_ans=0;
    for(int i=1;i<=m;i++)
    {
        int opt,x,y;
        opt=read();x=read();y=read();
        x^=last_ans;y^=last_ans;
        if(opt==0) {last_ans=divide_and_conquer_tree::query(x,y);cout<<last_ans<<endl;}
        else {divide_and_conquer_tree::change(x,y-a[x]);a[x]=y;}
    }
    ed=clock();
    cerr<<endl<<double(ed-st)<<"ms"<<endl;
    return 0;
}
2023/11/1 17:10
加载中...