codeforces1494E. A-Z Graph

https://codeforces.com/contest/1494/problem/E

我就说这题怎么过了200个只比D少100个过。。。大水题卧槽

这题的关键是能够走重复的点

这题首先根据样例提示发现k&1的时候很简单

只需要1->2->1->2->1....下去就行了,所以k为奇数的都能搞出来,那么我们只要记录是否存在从u->v再从v->u的边就行了,因为你就算v1->v2->v3这样3个,由于回文串的性质,还不如在原地两条边来回走

关键是k偶数的时候有点难,但是我们可以想到v1->v2->v3->vk k%2==0,由于回文串,所以中间的v_k/2 v_k/2+1之间一定是相同的,然而我们也可以只使用这两个之间的相同的边反复横跳得到所有k是偶数的一组解

所以只需要维护有多少对边和有多少对相同边就行了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxl=3e5+10;

int n,m,k,cnt,tot,cas,ans;
int a[maxl];
bool vis[maxl];
char opt[2],s[2];
map<ll,int> mp;

inline ll ed(int u,int v)
{
	return 1ll*u*(n+1)+v;
}

inline void prework()
{
	int cnt1=0,cnt2=0;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%s",opt);
		if(opt[0]!='?')
		{
			int u,v;
			scanf("%d%d",&u,&v);
			if(opt[0]=='+')
			{
				scanf("%s",s);
				mp[ed(u,v)]=s[0]-'a'+1;
				if(mp[ed(v,u)])
				{
					cnt1++;
					if(mp[ed(v,u)]==mp[ed(u,v)])
						cnt2++;
				}
			}
			else
			{
				if(mp[ed(v,u)])
				{
					cnt1--;
					if(mp[ed(v,u)]==mp[ed(u,v)])
						cnt2--;
				}
				mp[ed(u,v)]=0;
			}
		}
		else
		{
			scanf("%d",&k);
			if(k&1)
				puts(cnt1>0?"YES":"NO");
			else
				puts(cnt2>0?"YES":"NO");
		}
	}
}

inline void mainwork()
{
	
}

inline void print()
{
	
}

int main()
{
	int t=1;
	//scanf("%d",&t);
	for(cas=1;cas<=t;cas++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/114332115