P3401 求助!
查看原帖
P3401 求助!
79065
A1443356159楼主2020/7/31 16:35

不加懒惰标记就T,加了WA了.

#include<bits/stdc++.h>
#define N 30010
#define ls (i<<1)
#define rs (i<<1|1)
#define LL long long
using namespace std;
int n,q;
int read()
{
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return x*f;
}
struct Edge{int v,w,nxt;}e[N<<1];
int size,head[N];
void add(int u,int v,int w){e[++size].v=v;e[size].nxt=head[u];e[size].w=w;head[u]=size;}
int rev[N],seg[N],sze[N],val[N],dep[N],fa[N],son[N],top[N],cnt,lazy[N];
void dfs1(int u,int father)
{
	sze[u]=1;dep[u]=dep[father]+1;fa[u]=father;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(v==father)continue;
		val[v]=val[u]^e[i].w;
		dfs1(v,u);
		sze[u]+=sze[v];
		if(sze[v]>sze[son[u]])son[u]=v;
	}
}
void dfs2(int u)
{
	if(son[u])
	{
		int v=son[u];
		top[v]=top[u];
		rev[v]=++cnt;
		seg[cnt]=v;
		dfs2(v);
	}
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(!top[v])
		{
			top[v]=v;
			rev[v]=++cnt;
			seg[cnt]=v;
			dfs2(v);
		}
	}
}
struct Node{
	int num0[15],num1[15];
	Node operator +(const Node &q)const
	{
		Node res;
		for(int i=0;i<11;++i)
		{
			res.num0[i]=num0[i]+q.num0[i];
			res.num1[i]=num1[i]+q.num1[i];
		}
		return res;
	}
	void clear()
	{
		memset(num0,0,sizeof(num0));
		memset(num1,0,sizeof(num1));
	}
}sum[N<<2];
void change(int pos,int k)
{
	for(int i=0;i<11;++i)
	{
		if(k&(1<<i))swap(sum[pos].num0[i],sum[pos].num1[i]);
	}
	lazy[pos]^=k;
}
void pushdown(int i)
{
	if(lazy[i]==0)return;
	change(ls,lazy[i]);
	change(rs,lazy[i]);
	lazy[i]=0;
}
Node query(int i,int l,int r,int x,int y)
{
	if(x<=l&&r<=y)return sum[i];
	int mid=(l+r)>>1;
	Node res;
	res.clear();
	pushdown(i);
	if(x<=mid)res=res+query(ls,l,mid,x,y);
	if(y>mid)res=res+query(rs,mid+1,r,x,y);
	return res;
}
void update(int i,int l,int r,int x,int y,int k)
{
	if(x<=l&&r<=y)
	{
		change(i,k);
		return ;
	}
	pushdown(i);
	int mid=(l+r)>>1;
	if(x<=mid)update(ls,l,mid,x,y,k);
	if(y>mid)update(rs,mid+1,r,x,y,k);
	sum[i]=sum[ls]+sum[rs];
}
LL QUERY(int x,int y)
{
	int fx=top[x],fy=top[y];
	Node fuck;fuck.clear();
	while(fx!=fy)
	{
		if(dep[fx]<dep[fy])swap(fx,fy),swap(x,y);
		fuck=fuck+query(1,1,n,rev[fx],rev[x]);
		x=fa[fx];fx=top[x];
	}
	if(dep[x]<dep[y])swap(x,y);
	fuck=fuck+query(1,1,n,rev[y],rev[x]);
	LL res=0;
	for(int i=0;i<11;++i)res=res+1ll*fuck.num0[i]*fuck.num1[i]*(1LL<<i);
	return res;
}
void build(int i,int l,int r)
{
	if(l==r)
	{
		int x=seg[l];
		for(int j=0;j<11;++j)
		{
			if(val[x]&(1<<j))sum[i].num1[j]=1;
			else sum[i].num0[j]=1;
		}
		return ;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	sum[i]=sum[ls]+sum[rs];
}
int main()
{
	n=read();q=read();
	for(int i=1;i<n;++i)
	{
		int u=read(),v=read(),w=read();
		add(u,v,w);
		add(v,u,w);
	}
	dfs1(1,0);
	++cnt;rev[1]=1;seg[1]=1;top[1]=1;
	dfs2(1);
	build(1,1,n);
	int opt,u,v,w,lat;
	while(q--)
	{
		opt=read();u=read();v=read();
		if(opt==1)printf("%lld\n",QUERY(u,v));
		else
		{
			w=read();
			if(dep[u]<dep[v])swap(u,v);
			for(int i=head[u];i;i=e[i].nxt)
			{
				if(e[i].v==v)
				{
					lat=e[i].w;
					e[i].w=w;
					break;
				}
			}
			update(1,1,n,rev[u],rev[u]+sze[u]-1,w^lat);
		}
	}
	return 0;
}
2020/7/31 16:35
加载中...