求调,WA#4-#7,TLE#8-#10
查看原帖
求调,WA#4-#7,TLE#8-#10
555868
Lovya楼主2025/1/23 13:53
#include<iostream>
#include<cstdio>
#include<cmath>
#define lc p<<1
#define rc p<<1|1
using namespace std;
int n,m,k,w_make_id,w_opt,x,y,z,w_root,w_mod,w_head[100005],w_dep[100005],w_val[100005],w_new_val[100005],w_heavy_son[100005],w_chain_top[100005],w_id[100005],w_father[100005],w_size[100005];
struct node{
	int l,r;
	long long w_sum,w_add;
}w_tree[400005];
struct Node{
	int w_next,w_to;
}w_edge[400005];
void w_add(int u,int v)
{
	w_edge[++k].w_next=w_head[u];
	w_edge[k].w_to=v;
	w_head[u]=k;
}
void w_push_up(int p)
{
	w_tree[p].w_sum=w_tree[lc].w_sum+w_tree[rc].w_sum;
}
void w_push_down(int p)
{
	if(!w_tree[p].w_add)
		return;
	w_tree[lc].w_sum+=(w_tree[lc].r-w_tree[lc].l+1)*w_tree[p].w_add;
	w_tree[rc].w_sum+=(w_tree[rc].r-w_tree[rc].l+1)*w_tree[p].w_add;
	w_tree[lc].w_add+=w_tree[p].w_add;
	w_tree[rc].w_add+=w_tree[p].w_add;
	w_tree[p].w_add=0;
}
void w_dfs_0(int u,int v)
{
	w_father[u]=v;
	w_dep[u]=w_dep[v]+1;
	w_size[u]=1;
	for(int i=w_head[u];i;i=w_edge[i].w_next)
	{
		if(w_edge[i].w_to==v)
			continue;
		w_dfs_0(w_edge[i].w_to,u);
		w_size[u]+=w_size[w_edge[i].w_to];
		if(w_size[w_edge[i].w_to]>w_size[w_heavy_son[u]])
			w_heavy_son[u]=w_edge[i].w_to;
	}
}
void w_dfs_1(int u,int w_top)
{
	w_chain_top[u]=w_top;
	w_id[u]=++w_make_id;
	w_new_val[w_make_id]=w_val[u];
	if(!w_heavy_son[u])
		return;
	w_dfs_1(w_heavy_son[u],w_top);
	for(int i=w_head[u];i;i=w_edge[i].w_next)
	{
		if(w_edge[i].w_to==w_father[u]||w_edge[i].w_to==w_heavy_son[u])
			continue;
		w_dfs_1(w_edge[i].w_to,w_edge[i].w_to);
	}
}
void w_build(int p,int x,int y)
{
    w_tree[p]={x,y,w_new_val[x],0};
    if(x==y)
        return;
    int m=x+y>>1;
    w_build(lc,x,m);
    w_build(rc,m+1,y);
    w_push_up(p);
}
void w_update(int p,int x,int y,long long k)
{
    if(x<=w_tree[p].l&&w_tree[p].r<=y)
    {
        w_tree[p].w_sum+=(w_tree[p].r-w_tree[p].l+1)*k;
        w_tree[p].w_add+=k;
        return;
    }
    int m=w_tree[p].l+w_tree[p].r>>1;
    w_push_down(p);
    if(x<=m)
        w_update(lc,x,y,k);
    if(y>m)
        w_update(rc,x,y,k);
    w_push_up(p);
}
long long w_query(int p,int x,int y)
{
    if(x<=w_tree[p].l&&w_tree[p].r<=y)
        return w_tree[p].w_sum;
    int m=w_tree[p].l+w_tree[p].r>>1;
    w_push_down(p);
    long long w_temp=0;
    if(x<=m)
        w_temp+=w_query(lc,x,y);
    if(y>m)
        w_temp+=w_query(rc,x,y);
    return w_temp;
}
void w_update_chain(int x,int y,int k)
{
	while(w_chain_top[x]!=w_chain_top[y])
	{
		if(w_dep[w_chain_top[x]]<w_dep[w_chain_top[y]])
			swap(x,y);
		w_update(1,w_id[w_chain_top[x]],w_id[x],k);
		x=w_father[x];
	}
	if(w_dep[x]<w_dep[y])
		swap(x,y);
	w_update(1,w_id[y],w_id[x],k);
}
long long w_query_chain(int x,int y)
{
	long long w_temp=0;
	while(w_chain_top[x]!=w_chain_top[y])
	{
		if(w_dep[w_chain_top[x]]<w_dep[w_chain_top[y]])
			swap(x,y);
		w_temp+=w_query(1,w_id[w_chain_top[x]],w_id[x]);
		x=w_father[x];
	}
	if(w_dep[x]<w_dep[y])
		swap(x,y);
	w_temp+=w_query(1,w_id[y],w_id[x]);
	return w_temp;
}
void w_update_son_tree(int x,int k)
{
	w_update(1,w_id[x],w_id[x]+w_size[x]-1,k);
}
long long w_query_son_tree(int x)
{
	return w_query(1,w_id[x],w_id[x]+w_size[x]-1);
}
int main()
{
	scanf("%d %d %d %d",&n,&m,&w_root,&w_mod);
	for(int i=1;i<=n;i++)
		scanf("%d",&w_val[i]);
	for(int i=1;i<n;i++)
	{
		scanf("%d %d",&x,&y);
		w_add(x,y);
		w_add(y,x);
	}
	w_dfs_0(w_root,0);
	w_dfs_1(w_root,w_root);
	w_build(1,1,n);
	while(m--)
	{
		scanf("%d %d",&w_opt,&x);
		if(w_opt==1)
		{
			scanf("%d %d",&y,&z);
			w_update_chain(x,y,z);
		}
		else if(w_opt==2)
		{
			scanf("%d",&y);
			printf("%d\n",w_query_chain(x,y)%w_mod);
		}
		else if(w_opt==3)
		{
			scanf("%d",&y);
			w_update_son_tree(x,y);
		}
		else
			printf("%d\n",w_query_son_tree(x)%w_mod);
	}
	return 0;
}
2025/1/23 13:53
加载中...