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;
}