bzoj4419 [Shoi2013] Post Weibo difference

This kind of question is usually difference, and only need to push one level,

So for adding and deleting edges, you can directly eliminate the impact by difference.

Note that when you count the answers, you should also count the edges that are still there, which is equivalent to delete processing. You can judge by scanning and adding edges and deleting edges. Note that there may be multiple occurrences in the vector, and only count once


code:

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
vector<int>v[200005],chu[200005];
int n,m,ans[200005],i,j,o,cnt[200005],a,b,ci[200005];
char op[5];
int main()
{
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
	scanf("%s",op);
	if(op[0]=='!')
	{
		scanf("%d",&o);
		cnt[o]++;
	}
	if(op[0]=='+')
	{
		scanf("%d%d",&a,&b);
		v[a].push_back(b);
		ans[b]-=cnt[a];
		v[b].push_back(a);
		ans[a]-=cnt[b];
	}
		if(op[0]=='-')
	{
		scanf("%d%d",&a,&b);
		chu[a].push_back(b);
		ans[b]+=cnt[a];
		chu[b].push_back(a);
		ans[a]+=cnt[b];
	}
	
}


for(i=1;i<=n;i++)
{
	for(j=0;j<v[i].size();j++)
	ci[v[i][j]]=0;
	for(j=0;j<v[i].size();j++)
	ci[v[i][j]]++;
	for(j=0;j<chu[i].size();j++)
	ci[chu[i][j]]--;	
	for(j=0;j<v[i].size();j++)
if(ci[v[i][j]])ans[v[i][j]]+=cnt[i],ci[v[i][j]]=0;	
}
for(i=1;i<=n-1;i++)
printf("%d ",ans[i]);
printf("%d",ans[i]);
	
}


Guess you like

Origin blog.csdn.net/haobang866/article/details/79245429