ABC238E题解
观察到原数组的具体取值并不重要,我们需要的信息只是区间
于是不难想到一个思路:对于给定的一个区间
于是我们已知
这个可以直接用并查集维护,时间复杂度
代码:
#import <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=2e5+10;
const int mod=1e18;
int n,q,u,v,c;
char op;
struct Splay
{
int ch[maxn][2],fa[maxn],siz[maxn],val[maxn],sum[maxn],add[maxn],mul[maxn],rev[maxn];
void clear(int x)
{
ch[x][0]=ch[x][1]=fa[x]=siz[x]=val[x]=sum[x]=add[x]=rev[x]=0;
mul[x]=1;
}
int getch(int x)
{
return (ch[fa[x]][1]==x);
}
int isroot(int x)
{
clear(0);
return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
}
void maintain(int x)
{
clear(0);
siz[x]=(siz[ch[x][0]]+1+siz[ch[x][1]])%mod;
sum[x]=(sum[ch[x][0]]+val[x]+sum[ch[x][1]])%mod;
}
void pushdown(int x)
{
clear(0);
if(mul[x]!=1)
{
if(ch[x][0])
mul[ch[x][0]]=(mul[x]*mul[ch[x][0]])%mod,val[ch[x][0]]=(val[ch[x][0]]*mul[x])%mod,sum[ch[x][0]]=(sum[ch[x][0]]*mul[x])%mod,add[ch[x][0]]=(add[ch[x][0]]*mul[x])%mod;
if(ch[x][1])
mul[ch[x][1]]=(mul[x]*mul[ch[x][1]])%mod,val[ch[x][1]]=(val[ch[x][1]]*mul[x])%mod,sum[ch[x][1]]=(sum[ch[x][1]]*mul[x])%mod,add[ch[x][1]]=(add[ch[x][1]]*mul[x])%mod;
mul[x]=1;
}
if(add[x])
{
if(ch[x][0])
add[ch[x][0]]=(add[ch[x][0]]+add[x])%mod,val[ch[x][0]]=(val[ch[x][0]]+add[x])%mod,sum[ch[x][0]]=(sum[ch[x][0]]+add[x]*siz[ch[x][0]])%mod;
if(ch[x][1])
add[ch[x][1]]=(add[ch[x][1]]+add[x])%mod,val[ch[x][1]]=(val[ch[x][1]]+add[x])%mod,sum[ch[x][1]]=(sum[ch[x][1]]+add[x]*siz[ch[x][1]])%mod;
add[x]=0;
}
if(rev[x])
{
if(ch[x][0])
rev[ch[x][0]]^=1,swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
if(ch[x][1])
rev[ch[x][1]]^=1,swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
rev[x]=0;
}
}
void update(int x)
{
if(!isroot(x))
update(fa[x]);
pushdown(x);
}
void rotate(int x)
{
int y=fa[x],z=fa[y],chx=getch(x),chy=getch(y);
fa[x]=z;
if(!isroot(y))
ch[z][chy]=x;
ch[y][chx]=ch[x][chx^1];
fa[ch[x][chx^1]]=y;
ch[x][chx^1]=y;
fa[y]=x;
maintain(y);
maintain(x);
maintain(z);
}
void splay(int x)
{
update(x);
for(int f=fa[x];f=fa[x],!isroot(x);rotate(x))
if(!isroot(f))
rotate(getch(x)==getch(f)?f:x);
}
void access(int x)
{
for(int f=0;x;f=x,x=fa[x])
splay(x),ch[x][1]=f,maintain(x);
}
void makeroot(int x)
{
access(x);
splay(x);
swap(ch[x][0],ch[x][1]);
rev[x]^=1;
}
int find(int x)
{
access(x);
splay(x);
while(ch[x][0])
x=ch[x][0];
splay(x);
return x;
}
void final_mul(int u,int v,int c)
{
makeroot(u), access(v), splay(v);
val[v] = val[v] * c % mod;
sum[v] = sum[v] * c % mod;
mul[v] = mul[v] * c % mod;
}
void final_add(int u,int v,int c)
{
makeroot(u), access(v), splay(v);
val[v] = (val[v] + c) % mod;
sum[v] = (sum[v] + siz[v] * c % mod) % mod;
add[v] = (add[v] + c) % mod;
}
int query1(int u,int v)
{
makeroot(u), access(v), splay(v);
return sum[v];
}
void link(int u,int v)
{
if (find(u) != find(v))
makeroot(u), fa[u] = v;
}
void cut(int u,int v)
{
makeroot(u);
access(v);
splay(v);
if (ch[v][0] == u && !ch[u][1])
ch[v][0] = fa[u] = 0;
}
bool query2(int u,int v)
{
return find(u) == find(v);
}
}st;
int find(int x)
{
return st.find(x);
}
void merge(int u,int v)
{
st.link(u,v);
}//LCT-并查集
signed main()
{
ios::sync_with_stdio(0);
int n,q;
cin>>n>>q;
for(int i=1;i<=n+1;i++)
st.clear(i),st.maintain(i),st.splay(i);
while(q--)
{
int l,r;
cin>>l>>r;
st.link(r+1,l);//因为LCT不支持对0节点操作(否则会超时)所以坐标集体平移1
}
if(st.find(1)==st.find(n+1))
cout<<"Yes";
else
cout<<"No";
}