[loj3273]扫除

对所有23操作建立一个序列,问题即求一个点经过一段连续操作后的结果

建立线段树并将询问离线,考虑线段树上每一个节点,即是没有1操作且4操作均在末尾的子问题

(保证操作总数为$o(q\log q)$,即区间长度+拆分到此区间的询问数)

对于第$i$个操作,记$p_{i}\in \{0,1\}$为操作类型(分别指H和V操作)$,l_{i}$为操作参数

结论:记$L_{i}=\max_{1\le j<i,p_{i}\ne p_{j},L_{j}\le l_{i}<n-l_{j}}l_{j}+1$,则第$i$个操作被执行当且仅当(初始)$\begin{cases}y\le l_{i},x\ge L_{i}&p_{i}=0\\x\le l_{i},y\ge L_{i}&p_{i}=1\end{cases}$

关于操作执行的定义,具体如下(以$p_{i}=0$的情况为例):

(将操作时)称$y>l_{i}$的操作不执行,称$y\le l_{i}$且$x<n-l_{j}$的操作被执行,其余操作是否执行均可

对其归纳证明,根据对称性,不妨仅考虑$p_{i}=0$的情况($p_{i}=1$时类似)

充分性:若$y\le l_{i},x\ge L_{i}$,根据归纳假设,之前会使得$y>l_{i}$的操作均不执行,进而最终$y\le l_{i}$

必要性:反证法,假设第$i$个操作被执行但不满足$x\ge L_{i}$($y\le l_{i}$显然满足)

根据$L_{i}$的定义,即存在$1\le j<i$满足$p_{j}=1,L_{j}\le l_{i}<n-l_{j},x\le l_{j}$

显然第$j$个操作不能被执行,即该时刻必然有$x>l_{j}>n-l_{i}$,那么第$ii个操作也可以不被执行

通过线段树$o(q\log n)$得到$L_{i}$,进而根据上述结论类似的$o(q\log n)$求出结果

时间复杂度为$o(q\log q\log n)$,可以通过

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define N 1000005
  4 #define pii pair<int,int>
  5 #define fi first
  6 #define se second
  7 #define L (k<<1)
  8 #define R (L+1)
  9 #define mid (l+r>>1)
 10 vector<int>v[N<<2];
 11 int n,m,t,q,k,p,num[11],T[N],id[N],f[N];
 12 pii P[N<<1],Q[N],a[N],ans[N];
 13 int read(){
 14     int x=0;
 15     char c=getchar();
 16     while ((c<'0')||(c>'9'))c=getchar();
 17     while ((c>='0')&&(c<='9')){
 18         x=x*10+c-'0';
 19         c=getchar();
 20     }
 21     return x;
 22 }
 23 void write(int x,char c='\0'){
 24     while (x){
 25         num[++num[0]]=x%10;
 26         x/=10;
 27     }
 28     if (!num[0])putchar('0');
 29     while (num[0])putchar(num[num[0]--]+'0');
 30     putchar(c);
 31 }
 32 struct Tree{
 33     int V,rt,ls[N*50],rs[N*50],mx[N*50];
 34     void init(){
 35         V=rt=0;
 36     }
 37     int New(){
 38         int k=++V;
 39         ls[k]=rs[k]=mx[k]=0;
 40         return k;
 41     }
 42     void update(int &k,int l,int r,int x,int y,int z){
 43         if ((l>y)||(x>r))return;
 44         if (!k)k=New();
 45         if ((x<=l)&&(r<=y)){
 46             mx[k]=max(mx[k],z);
 47             return;
 48         }
 49         update(ls[k],l,mid,x,y,z);
 50         update(rs[k],mid+1,r,x,y,z);
 51     }
 52     int query(int k,int l,int r,int x){
 53         if (!k)return 0;
 54         if (l==r)return mx[k];
 55         if (x<=mid)return max(query(ls[k],l,mid,x),mx[k]);
 56         return max(query(rs[k],mid+1,r,x),mx[k]);
 57     }
 58     void update(int x,int y,int z){
 59         update(rt,0,n,x,y,z);
 60     }
 61     int query(int k){
 62         return query(rt,0,n,k);
 63     }
 64 }F[2];
 65 bool cmp(int x,int y){
 66     return f[x]<f[y];
 67 }
 68 bool cmpx(int x,int y){
 69     return ans[x].fi<ans[y].fi;
 70 }
 71 bool cmpy(int x,int y){
 72     return ans[x].se<ans[y].se;
 73 }
 74 void add(int k,int l,int r,int x,int y,int z){
 75     if ((l>y)||(x>r))return;
 76     if ((x<=l)&&(r<=y))v[k].push_back(z);
 77     else add(L,l,mid,x,y,z),add(R,mid+1,r,x,y,z);
 78 }
 79 void dfs(int k,int l,int r){
 80     F[0].init(),F[1].init();
 81     for(int i=l;i<=r;i++){
 82         f[i]=F[a[i].fi^1].query(a[i].se);
 83         F[a[i].fi].update(f[i],n-a[i].se-1,a[i].se+1);
 84     }
 85     F[0].init(),F[1].init();
 86     id[0]=0;
 87     for(int i=l;i<=r;i++)
 88         if (!a[i].fi)id[++id[0]]=i;
 89     sort(id+1,id+id[0]+1,cmp);
 90     sort(v[k].begin(),v[k].end(),cmpx);
 91     for(int i=0,j=1;i<v[k].size();i++){
 92         int Id=v[k][i];
 93         while ((j<=id[0])&&(f[id[j]]<=ans[Id].fi)){
 94             F[0].update(0,a[id[j]].se,n-a[id[j]].se);
 95             j++;
 96         }
 97         ans[Id].fi=max(ans[Id].fi,F[0].query(ans[Id].se));
 98     }
 99     id[0]=0;
100     for(int i=l;i<=r;i++)
101         if (a[i].fi)id[++id[0]]=i;
102     sort(id+1,id+id[0]+1,cmp);
103     sort(v[k].begin(),v[k].end(),cmpy);
104     for(int i=0,j=1;i<v[k].size();i++){
105         int Id=v[k][i];
106         while ((j<=id[0])&&(f[id[j]]<=ans[Id].se)){
107             F[1].update(0,a[id[j]].se,n-a[id[j]].se);
108             j++;
109         }
110         ans[Id].se=max(ans[Id].se,F[1].query(ans[Id].fi));
111     }
112     if (l>=r)return;
113     dfs(L,l,mid),dfs(R,mid+1,r);
114 }
115 int main(){
116     n=read(),k=read(),m=read();
117     for(int i=1;i<=k;i++)P[i].fi=read(),P[i].se=read();
118     for(int i=1;i<=m;i++){
119         p=read();
120         if (p==1)Q[++q]=make_pair(read(),t);
121         if ((p==2)||(p==3))a[++t]=make_pair(p-2,read());
122         if (p==4)P[++k].fi=read(),P[k].se=read(),T[k]=t;
123     }
124     for(int i=1;i<=q;i++){
125         ans[i]=P[Q[i].fi];
126         add(1,1,t,T[Q[i].fi]+1,Q[i].se,i);
127     }
128     dfs(1,1,t);
129     for(int i=1;i<=q;i++)write(ans[i].fi,' '),write(ans[i].se,'\n');
130     return 0;
131 }
View Code

 

posted @ 2020-05-09 07:10  PYWBKTDA  阅读(240)  评论(0编辑  收藏  举报