[cf319E]Ping-Pong

分析条件,不难发现仅有以下两类边:

1.若两区间严格相交(有公共段)且不相互包含,则两区间之间有双向边

2.若两区间相互包含,则小区间向大区间有单向边

对于第1类边,由于区间长度严格递增,可以通过线段树+并查集维护

具体的,1操作时在(线段树)区间$(l,r)$上加入该点,并与在$l$和$r$处已加入的点连边

可以使用vector暴力维护加入的点,并在连边后仅保留其中第一个点,显然可以均摊

引理:若$a$可以到$b$,则存在一条$a$到$b$的路径,使得(至多)仅有第1步用了第2类边

根据移动的条件,显然可以(跳过小区间)直接移动到大区间

结合引理,即要求$a$本身或某个包含$a$的区间与$b$在同一个并查集中

前者可以直接判定,(在前者不成立时)后者有以下结论——

结论:其成立当且仅当$a$被$b$所在并查集中所有区间的并包含

必要性显然,考虑充分性——

取$b$所在并查集中包含$a$左端点向右单位长度段的区间,显然这样的区间存在

若该区间包含$a$即得证,否则显然$a$不包含该区间,进而两者有双向边,与前者不成立矛盾

总复杂度为$o(n\log V)$,可以通过

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 100005
 4 #define mid (l+r>>1)
 5 pair<int,int>a[N];
 6 vector<int>v[N*100];
 7 int n,m,V,rt,p,l,r,fa[N],L[N],R[N],ls[N*100],rs[N*100];
 8 int find(int k){
 9     if (k==fa[k])return k;
10     return fa[k]=find(fa[k]);
11 }
12 void merge(int x,int y){
13     x=find(x),y=find(y);
14     if (x==y)return;
15     fa[y]=x,L[x]=min(L[x],L[y]),R[x]=max(R[x],R[y]);
16 }
17 void update(int &k,int l,int r,int x,int y,int z){
18     if ((l>y)||(x>r))return;
19     if (!k)k=++V;
20     if ((x<=l)&&(r<=y)){
21         v[k].push_back(z);
22         return;
23     }
24     update(ls[k],l,mid,x,y,z);
25     update(rs[k],mid+1,r,x,y,z);
26 }
27 void add(int k,int l,int r,int x,int y){
28     if (!k)return;
29     if (!v[k].empty()){
30         for(int i=0;i<v[k].size();i++)merge(y,v[k][i]);
31         v[k].resize(1);
32     }
33     if (l==r)return;
34     if (x<=mid)add(ls[k],l,mid,x,y);
35     else add(rs[k],mid+1,r,x,y);
36 }
37 int main(){
38     scanf("%d",&n);
39     for(int i=1;i<=n;i++){
40         scanf("%d%d%d",&p,&l,&r);
41         if (p==1){
42             a[++m]=make_pair(l,r);
43             fa[m]=m,L[m]=l,R[m]=r;
44             if (r-l>=2)update(rt,-1e9,1e9,l+1,r-1,m);
45             add(rt,-1e9,1e9,l,m),add(rt,-1e9,1e9,r,m);
46         }
47         if (p==2){
48             r=find(r);
49             if ((find(l)==r)||(L[r]<=a[l].first)&&(a[l].second<=R[r]))printf("YES\n");
50             else printf("NO\n");
51         }
52     }
53     return 0;
54 }
View Code

 

posted @ 2022-03-21 18:40  PYWBKTDA  阅读(67)  评论(0编辑  收藏  举报