[loj3273]扫除

先考虑子任务4,容易发现如果一堆2操作和一堆3操作的顺序是可以调换的,但2操作和3操作的相对顺序不能调换,因此考虑2操作和3操作之间的影响
设两个操作分别为2 a和3 b,第一个操作会影响到$x<n-a$和$yle a$的点,第二个操作会影响到$xle b$且$y<n-b$的点,因此分为两种情况:1.$n-ale b$,那么两者没有顺序要求;2.$b<n-a$,那么第二个操作只会影响到$xle b$且$a<y<n-b$的点,因此实际上要找到满足$b<n-a$的最大的a
先根据这个用线段树预处理出每一个操作真正影响的范围,我们就可以把两种操作分开进行了:(以2操作为例)如果点是从y从大到小排序将y按照a排序,将点也按照y从大到小排序,对两个进行单调性的操作即可
考虑维护插入操作,插入后每一个点的修改区间就不一样了,所以用线段树分治来避免插入操作即可

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define N 1500005
  4 #define mid (l+r>>1)
  5 #define fi first
  6 #define se second
  7 #define L T[p].ls[k]
  8 #define R T[p].rs[k]
  9 #define T(x) (x),T[x].r,0,n
 10 vector<int>vec;
 11 vector<pair<int,int> >u[2];
 12 struct ji{
 13     int t,x,y;
 14 }a[N];
 15 struct qu{
 16     int l,r,x,y;
 17 }Q[N];
 18 struct up{
 19     int op,len;
 20 }b[N];
 21 struct tree{
 22     int  V,r,mx[N*20],ls[N*20],rs[N*20];
 23 }T[2];
 24 int n,m,q,t,q0,p,x,y;
 25 bool cmp1(int x,int y){
 26     return Q[x].y>Q[y].y;
 27 }
 28 bool cmp2(int x,int y){
 29     return Q[x].x>Q[y].x;
 30 }
 31 void update(int p,int &k,int l,int r,int x,int y,int z){
 32     if ((x>y)||(l>y)||(x>r))return;
 33     if (!k){
 34         k=++T[p].V;
 35         L=R=T[p].mx[k]=0;
 36     }
 37     if ((x<=l)&&(r<=y)){
 38         T[p].mx[k]=max(T[p].mx[k],z);
 39         return;
 40     }
 41     update(p,L,l,mid,x,y,z);
 42     update(p,R,mid+1,r,x,y,z);
 43 }
 44 int query(int p,int k,int l,int r,int x){
 45     if (!k)return 0;
 46     if (l==r)return T[p].mx[k];
 47     if (x<=mid)return max(T[p].mx[k],query(p,L,l,mid,x));
 48     return max(T[p].mx[k],query(p,R,mid+1,r,x));
 49 }
 50 void dfs(int l,int r,vector<int> vec){
 51     if ((!vec.size()))return;
 52     vector<int> v,ls,rs;
 53     for(int i=0;i<vec.size();i++){
 54         qu o=Q[vec[i]];
 55         if ((o.l<=l)&&(r<=o.r))v.push_back(vec[i]);
 56         else{
 57             if (o.l<=mid)ls.push_back(vec[i]);
 58             if (mid<o.r)rs.push_back(vec[i]);
 59         }
 60     }
 61     dfs(l,mid,ls);
 62     dfs(mid+1,r,rs);
 63     if (!v.size())return;
 64     T[0].V=T[0].r=T[1].V=T[1].r=0;
 65     u[0].clear();
 66     u[1].clear();
 67     for(int i=l;i<=r;i++){
 68         int k=query(T(b[i].op^1),b[i].len);
 69         u[b[i].op].push_back(make_pair(b[i].len,k));
 70         update(T(b[i].op),k,n-b[i].len-1,b[i].len+1);
 71     }
 72     T[0].V=T[0].r=T[1].V=T[1].r=0;
 73     sort(u[0].begin(),u[0].end());
 74     sort(u[1].begin(),u[1].end());
 75     sort(v.begin(),v.end(),cmp1);
 76     for(int i=0,j=u[0].size()-1;i<v.size();i++){
 77         while ((j>=0)&&(u[0][j].fi>=Q[v[i]].y)){
 78             update(T(0),u[0][j].se,n-u[0][j].fi,n-u[0][j].fi);
 79             j--;
 80         }
 81         Q[v[i]].x=max(Q[v[i]].x,query(T(0),Q[v[i]].x));
 82     }
 83     sort(v.begin(),v.end(),cmp2);
 84     for(int i=0,j=u[1].size()-1;i<v.size();i++){
 85         while ((j>=0)&&(u[1][j].fi>=Q[v[i]].x)){
 86             update(T(1),u[1][j].se,n-u[1][j].fi,n-u[1][j].fi);
 87             j--;
 88         }
 89         Q[v[i]].y=max(Q[v[i]].y,query(T(1),Q[v[i]].y));
 90     }
 91 }
 92 int main(){
 93     srand(time(0));
 94     scanf("%d%d%d",&n,&m,&q);
 95     for(int i=1;i<=m;i++){
 96         scanf("%d%d",&x,&y);
 97         a[i]=ji{0,x,y};
 98     }
 99     for(int i=1;i<=q;i++){
100         scanf("%d%d",&p,&x);
101         if (p==1){
102             vec.push_back(++q0);
103             Q[q0]=qu{a[x].t+1,t,a[x].x,a[x].y};
104         }
105         if ((1<p)&&(p<4)){
106             if (x==n)continue;
107             b[++t]=up{p-2,x};
108         }
109         if (p==4){
110             scanf("%d",&y);
111             a[++m]=ji{t,x,y};
112         }
113     }
114     dfs(1,t,vec);
115     for(int i=1;i<=q0;i++)printf("%d %d
",Q[i].x,Q[i].y);
116 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/12854554.html