社区讨论

我好不容易学会树上莫队,你却让我WA得这么彻底

P4074[WC2013] 糖果公园参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@lwqae9yq
此快照首次捕获于
2024/05/28 19:01
2 年前
此快照最后确认于
2024/05/28 20:38
2 年前
查看原帖
rt,40pts,求活雷锋帮条QAQ。
CPP
#include<bits/stdc++.h>
#define int long long
#define pos(x) (x/qn+bool(x%qn))
using namespace std;
const int cxk=4e5+5;
vector<int>nbr[cxk];
int n,m,qn,k,tot,ans,w[cxk],v[cxk],to[cxk],num[cxk],cnt[cxk],c[cxk],dp[cxk][22],dep[cxk],in[cxk],out[cxk];
struct ikun
{
	int lt,rt,t,l,i;
	friend bool operator<(const ikun&x,const ikun&y)
	{
		if(pos(x.lt)!=pos(y.lt))
			return pos(x.lt)<pos(y.lt);
		if(pos(x.rt)!=pos(y.rt))
			return pos(x.rt)<pos(y.rt);
		return pos(x.t)<pos(y.t); 
	}
}q[cxk];
pair<int,int>p[cxk];
bool vis[cxk];
void dfs(int cur,int fa)
{
	dp[cur][0]=fa;
	for(int i=1;i<=21;i++)
		dp[cur][i]=dp[dp[cur][i-1]][i-1];
	dep[cur]=dep[fa]+1;
	to[in[cur]=++tot]=cur;
	for(int nxt:nbr[cur])
	{
		if(nxt==fa)
			continue;
		dfs(nxt,cur);
	}
	to[out[cur]=++tot]=cur;
}
int lca(int x,int y)
{
	if(dep[x]<dep[y])
		swap(x,y);
	for(int i=21;i>=0;i--)
		if(dep[dp[x][i]]>=dep[y])
			x=dp[x][i];
	if(x==y)
		return x;
	for(int i=21;i>=0;i--)
		if(dp[x][i]!=dp[y][i])
		{
			x=dp[x][i];
			y=dp[y][i];
		}
	return dp[x][0];
}
void insert(int x)
{
	vis[to[x]]^=1;
	if(vis[to[x]])
	{
		cnt[c[x]]++;
		ans+=w[cnt[c[x]]]*v[c[x]];
	}
	else
	{
		ans-=w[cnt[c[x]]]*v[c[x]];
		cnt[c[x]]--;
	}
}
//void erase(int x)本质上和insert一样
//{
//	if(vis[to[x]]==0)
//		ans+=w[++cnt[c[x]]]*v[c[x]];
//	else
//		ans-=w[cnt[c[x]]--]*v[c[x]];
//	vis[to[x]]^=1;
//}
void takes(int lt,int rt,int t)
{
	int x=p[t].first,&y=p[t].second;
	if(lt<=x&&x<=rt)
		if(vis[to[x]])
		{
			ans-=w[cnt[c[x]]--]*v[c[x]];
			ans+=w[++cnt[y]]*v[y];
		} 
		else
		{
			ans+=w[++cnt[c[x]]]*v[c[x]];
			ans-=w[cnt[y]--]*v[y];
		}
	swap(c[x],y);
}
signed main()
{
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>n>>m>>k;
	qn=sqrt(2*n);
	for(int i=1;i<=m;i++)
		cin>>v[i];
	for(int i=1;i<=n;i++)
		cin>>w[i];
	for(int i=1,x,y;i<n;i++)
	{
		cin>>x>>y;
		nbr[x].push_back(y);
		nbr[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++)
	{
		cin>>c[in[i]];
		c[out[i]]=c[in[i]];
	}
	int s1=0,s2=0;
	for(int i=1,opt,x,y,l;i<=k;i++)
	{
		cin>>opt>>x>>y;
		if(opt==0)
		{
			p[++s1]={in[x],y};
			p[++s1]={out[x],y};
		}
		else
		{
			if(in[x]>in[y])
				swap(x,y);
			l=lca(x,y);
			s2++;
			if(l==x)
				q[s2]={in[x],in[y],s1,0,s2};
			else
				q[s2]={out[x],in[y],s1,in[l],s2};
		}
	}
	sort(q+1,q+s2+1);
	for(int i=1,lt=1,rt=0,t=0;i<=s2;i++)
	{
		int x=q[i].lt,y=q[i].rt,z=q[i].t;
		while(rt<y)
			insert(++rt);
		while(y<rt)
			insert(rt--);
		while(lt<x)
			insert(lt++);
		while(x<lt)
			insert(--lt);
		while(t<z)
			takes(lt,rt,++t);
		while(z<t)
			takes(lt,rt,t--);
		num[q[i].i]=ans;
		if(q[i].l)
			num[q[i].i]+=w[cnt[c[q[i].l]]+1]*v[c[q[i].l]];
	}
	for(int i=1;i<=s2;i++)
		cout<<num[i]<<"\n";
}

回复

4 条回复,欢迎继续交流。

正在加载回复...