description
solution
这里的单点询问需要全部的修改才能统计出答案
需要用到线段树分治的另一个形式:
在树上(DFS)维护数据结构,进入叶子的时候求出询问答案,回溯的时候栈序撤销
数据结构选择的是并查集,维护连通性和到达代表元(根节点)的路径长度奇偶性,合并的时候判断是否出现奇环即可
写了一个比较直接的内存修改的撤销
空间227M
千万别学我
code
#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define FILE "a"
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e9+7;
const int N=2e5+10;
const dd pi=acos(-1);
const int inf=2147483647;
const ll INF=1e18+1;
il ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
}
int n,m,T;
struct modify{int u,v;}M[N];vector<modify>f[N<<4];
struct data{int o,id,x;};vector<data>g[N<<4];
#define mid ((l+r)>>1)
#define ls (t<<1)
#define rs (t<<1|1)
void insertmodify(int t,int l,int r,int x,int y,modify m){
if(x<=l&&r<=y){f[t].pb(m);return;}
if(x<=mid)insertmodify(ls,l,mid,x,y,m);
if(mid<y)insertmodify(rs,mid+1,r,x,y,m);
}
int fa[N],sz[N],dis[N],now;
int find(int x){
if(fa[x]==x)return x;
RG int ff=find(fa[x]);
if(dis[fa[x]]){
g[now].pb((data){3,x,dis[x]});
dis[x]^=1;
}
if(fa[x]!=ff){
g[now].pb((data){1,x,fa[x]});
fa[x]=ff;
}
return fa[x];
il bool merge(int u,int v){
RG int fu=find(u),fv=find(v);
if(fu==fv)return dis[u]^dis[v];
if(sz[fu]>sz[fv])swap(u,v),swap(fu,fv);
g[now].pb((data){1,fu,fa[fu]});
fa[fu]=fv;
g[now].pb((data){2,fv,sz[fv]});
sz[fv]+=sz[fu];
g[now].pb((data){3,fu,dis[fu]});
dis[fu]=dis[u]^dis[v]^1;
return 1;
}
il void recover(int t){
while(g[t].size()){
RG data a=g[t][g[t].size()-1];
if(a.o==1)fa[a.id]=a.x;
if(a.o==2)sz[a.id]=a.x;
if(a.o==3)dis[a.id]=a.x;
g[t].pop_back();
}
}
void segdiv(int t,int l,int r){
now=t;
for(RG int i=0,sz=f[t].size();i<sz;i++)
if(!merge(f[t][i].u,f[t][i].v)){
for(RG int j=l;j<=r;j++)puts("No");
recover(t);
return;
}
if(l==r){puts("Yes");recover(t);return;}
segdiv(ls,l,mid);segdiv(rs,mid+1,r);
recover(t);
}
int main()
{
n=read();m=read();T=read();
for(RG int i=1;i<=n;i++)fa[i]=i,sz[i]=1,dis[i]=0;
for(RG int i=1,l,r;i<=m;i++){
M[i].u=read();M[i].v=read();
l=read()+1;r=read();
insertmodify(1,1,T,l,r,M[i]);
}
segdiv(1,1,T);
return 0;
}