bzoj4419 [Shoi2013]发微博 差分

这种题一般都是差分,而且只用推一层,

所以对于加边和删边就直接差分消除影响即可

注意统计答案的时候还在的边也要统计,相当于做删除处理,扫一遍加边删边即可判断,注意在vector里可能出现多次,只统计一次


码:

#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]);
	
}


猜你喜欢

转载自blog.csdn.net/haobang866/article/details/79245429