题目大意:
给你一张图多次询问两点路径是否为奇数。
题解:
一看就是个圆方树
想了想细节挺多就弃疗了
然后想了一个假做法,即随便弄出一个dfs树然后询问路径如果和非树边产生的奇环相交就是yes。这样场上并没有过大样例但是只有一个误差(共1e5组询问)。后来闲的没事把边表和dfs序列random_shuffle了一遍,然后……咦我怎么80分了?然后改成跑十遍这个随机然后就过了……
顺带在cf上也能过。
upd:后来被发现是可以被卡的,加了个奇怪的东西仍然过了。但是只保留一开始的代码(圆方树在后面):
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define N 100010
#define M 100010
#define LOG 20
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
int d[N],up[N][LOG],Log[N],vis[N],bel[N],id[N],ql[N];
int qx[N],qy[N],isno[N];lint val[N];vector<int> g[N],to[N];
lint dfs(int x,int fa,int cnt)
{
memset(up[x],0,sizeof up[x]);
d[x]=d[fa]+1,vis[x]=1,bel[x]=cnt,up[x][0]=fa;
for(int i=1;i<=Log[d[x]];i++) up[x][i]=up[up[x][i-1]][i-1];
for(int i=0,y;i<(int)to[x].size();i++) if((y=to[x][i])^fa)
{
if(!vis[y]) val[x]+=dfs(y,x,cnt),g[x].pb(y);
else if(vis[y]==1&&(d[x]&1)==(d[y]&1)) val[x]++,val[y]--;
}
return vis[x]=2,val[x];
}
int getval(int x,int fa=0) { val[x]+=val[fa];Rep(i,g[x]) getval(g[x][i],x);return 0; }
inline int getLCA(int x,int y)
{
if(d[x]<d[y]) swap(x,y);
for(int i=Log[d[x]];i>=0;i--)
if(d[up[x][i]]>=d[y]) x=up[x][i];
if(x==y) return x;
for(int i=Log[d[x]];i>=0;i--)
if(up[x][i]^up[y][i]) x=up[x][i],y=up[y][i];
return up[x][0];
}
char ss[1000000];int ssl;
int main()
{
srand((unsigned int)(time(0)-20010817-20010916));
int n=inn(),m=inn(),x,y;rep(i,2,n) Log[i]=Log[i>>1]+1;
rep(i,1,m) x=inn(),y=inn(),to[x].pb(y),to[y].pb(x);
int q=inn(),qcnt=q;rep(i,1,n) id[i]=i;
rep(i,1,q) qx[i]=inn(),qy[i]=inn(),ql[i]=i;
for(int Tms=25;qcnt&&Tms;Tms--)
{
rep(x,1,n) g[x].clear(),val[x]=0;int cnt=0;
rep(x,1,n) random_shuffle(to[x].begin(),to[x].end());
memset(vis,0,sizeof(int)*(n+1)),random_shuffle(id+1,id+n+1);
rep(i,1,n) if(!vis[id[i]]) d[id[i]]=0,dfs(id[i],0,++cnt),getval(id[i]);
rep(i,1,qcnt)
{
int x=qx[ql[i]],y=qy[ql[i]];
if(bel[x]^bel[y]) { isno[ql[i]]=1;continue; }
if((d[x]&1)!=(d[y]&1)) { isno[ql[i]]=0;continue; }
int c=getLCA(x,y);
if(val[x]+val[y]-2*val[c]) isno[ql[i]]=0;
else isno[ql[i]]=1;
}
int qc=0;
rep(i,1,qcnt) if(isno[ql[i]]) ql[++qc]=ql[i];
qcnt=qc;
}
rep(i,1,q)
if(isno[i]) ss[++ssl]='N',ss[++ssl]='o',ss[++ssl]='\n';
else ss[++ssl]='Y',ss[++ssl]='e',ss[++ssl]='s',ss[++ssl]='\n';
return fwrite(ss+1,sizeof(char),ssl,stdout),0;
}
圆方树
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define N 400010
#define LOG 21
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
struct edges{
int to,pre,id;
}e[N<<1];int h[N],etop,val[N],vis[N],low[N],dfn[N],dfc,d[N],dys[N],ecnt;
stack<int> s,es;int bel[N],eb[N],nc,f[N],up[N][LOG],Log[N];pii edg[N];
inline int add_edge(int u,int v,int id) { return e[++etop].to=v,e[etop].pre=h[u],e[etop].id=id,h[u]=etop; }
int tarjan(int x,int fa=0)
{
s.push(x),vis[x]=1,low[x]=dfn[x]=++dfc;
for(int i=h[x],y;i;i=e[i].pre) if((y=e[i].to)^fa)
{
if(!vis[y])
{
es.push(e[i].id),tarjan(y,x),low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x])
{
edg[++ecnt]=mp(x,++nc);
for(int z;dfn[z=s.top()]>=dfn[y];s.pop())
vis[z]=2,edg[++ecnt]=mp(z,nc);
while(es.top()^e[i].id) eb[es.top()]=nc,es.pop();
eb[e[i].id]=nc,es.pop();
}
}
else if(vis[y]==1)
{
low[x]=min(low[x],dfn[y]);
if(dfn[y]<dfn[x]) es.push(e[i].id);
}
}
return 0;
}
int dfs(int x,int fa,int cnt)
{
vis[x]=1,bel[x]=cnt,dys[x]=dys[fa]+1;
for(int i=h[x],y;i;i=e[i].pre) if((y=e[i].to)^fa)
{
if(!vis[y]) dfs(y,x,cnt);
else if(vis[y]==1&&(dys[x]&1)==(dys[y]&1)) f[eb[e[i].id]]++;
}
return vis[x]=2;
}
int solve(int x,int fa=0)
{
vis[x]=1,up[x][0]=fa,d[x]=d[fa]+1,f[x]+=f[fa];
rep(i,1,Log[d[x]]) up[x][i]=up[up[x][i-1]][i-1];
for(int i=h[x],y;i;i=e[i].pre)
if(!vis[y=e[i].to]) solve(y,x);
return 0;
}
inline int getLCA(int x,int y)
{
if(d[x]<d[y]) swap(x,y);
for(int i=Log[d[x]];i>=0;i--)
if(up[x][i][d]>=y[d]) x=up[x][i];
if(x==y) return x;
for(int i=Log[d[x]];i>=0;i--)
if(up[x][i]^up[y][i]) x=up[x][i],y=up[y][i];
return up[x][0];
}
int main()
{
int n=inn(),m=inn(),x,y,cnt=0;nc=n;
rep(i,1,m) x=inn(),y=inn(),add_edge(x,y,i),add_edge(y,x,i);
rep(i,1,n) if(!vis[i]) tarjan(i);
memset(vis,0,sizeof(int)*(n+1));
rep(i,1,n) if(!vis[i]) dfs(i,0,++cnt);
memset(h,0,sizeof(int)*(n+1)),etop=0;
rep(i,1,ecnt)
add_edge(edg[i].fir,edg[i].sec,0),
add_edge(edg[i].sec,edg[i].fir,0);
n=nc;
memset(vis,0,sizeof(int)*(n+1));
rep(i,2,n) Log[i]=Log[i>>1]+1;
rep(i,1,n) if(!vis[i]) solve(i);
for(int curq=1,q=inn();curq<=q;curq++)
{
int x=inn(),y=inn();
if(bel[x]^bel[y]) { printf("No\n");continue; }
if((dys[x]&1)^(dys[y]&1)) { printf("Yes\n");continue; }
int c=getLCA(x,y);
if(f[x]+f[y]-f[c]-f[up[c][0]]) printf("Yes\n");
else printf("No\n");
}
return 0;
}