『Raiden Ei』 Round 1千手百眼,天下人间题解

题目背景

影小姐在创作小说《转生成为八重宫司,然后天下无敌》。

但是由于神子不定时会过来贴贴,所以她不得不在神子来到时对所写的文稿进行掩饰甚至撤销,所以导致整个写作过程乱七八糟。

现在她很生气,请你在她生气的拔刀斩了你之前回答她的所有问题。

题目描述

我们将提瓦特文抽象成正整数数字。

初始时影有序列 A 作为草稿,长度为 n。

但是写着写着,她心情总是飘忽不定的变化,所以草稿也会随之变化。

有以下三种可能的事件:

  1. 在第 ti​ 时刻,将 li​ 到 ri​ 的所有值增加 ki​。
  2. 在第 ti​ 时刻,查询区间 li​ 到 ri​ 之间所有数的最大值。
  3. 在第 ti​ 时刻,将 li​ 到 ri​ 这些时间点发生的三种事件全部撤销。

在影写完冷静下来之后,请你对于所有未被撤销的查询进行回答。

输入格式

第一行输入两个正整数 n,m。

第二行输入 n 个整数,表示序列 A。

接下来 m 行,每行输入第一个元素 opt 作为操作类型。

  • 若 opt=1,则按顺序输入 ti​,li​,ri​,ki​,表示一次修改,满足 −109≤ki​≤109。

  • 若 opt=2,则按顺序输入 ti​,li​,ri​,表示一次查询。

  • 若 opt=3,则按顺序输入 ti​,li​,ri​,表示一次撤销,满足 li​≤ri​<ti​。

输出格式

第一行输出一个整数 cnt,表示有效的查询次数。

接下来 cnt 行,每行一个整数作为答案。

注意:你所输出的答案应按照时间顺序,若两个查询时间相同,则优先回答操作编号较小的那次查询,同理,两个操作时间相同时优先执行编号小的操作。

输入输出样例

输入 #1复制

3 5
0 0 0 
1 1 1 3 5
2 2 1 3
3 3 1 1
2 4 1 3
1 5 1 1 10

输出 #1复制

2
0
0

输入 #2复制

3 4
1 2 3
1 1 1 3 5
2 2 1 3
3 3 2 2
2 4 1 3

输出 #2复制

1
8

说明/提示

对于前 10% 的数据,满足 n,m≤10。

对于另 20% 的数据,满足不含有撤销操作。

对于另 10% 的数据,满足没有修改操作。

对于 100% 的数据,满足 1≤n,m≤5×105,−109≤Ai​≤109,1≤ti​≤1018。

思路

看到区间操作,考虑线段树,然后从后向前扫,去除删除项即可。

代码见下

#include<bits/stdc++.h>
using namespace std;
// map<long long,long long> mp;
int opt[500005],n,m,a[500005],k[500005];
int te[4000006];
int lz[4000006];
int df=0;
int cf[1500006],cf2[1500006];
struct one{
    int opt,k,i;
    long long t,l,r;
}aa[500005];
bool cmp2(one a1,one b1){
    if(a1.t!=b1.t){
        return a1.t<b1.t;
    }
    else{
        return a1.i<b1.i;
    }
}
void alz(int a1,int v){
	te[a1]+=v;
	lz[a1]+=v;
}//a1打标记值v
void dow(int a1){
	alz(a1*2,lz[a1]);
	alz(a1*2+1,lz[a1]);
	lz[a1]=0;
}//a1下发标记至儿子
void bu(int a1,int l,int r){
	if(l==r){
		te[a1]=a[l];
		return ;
	}
	int mid=(l+r)/2;
	bu(a1*2,l,mid);
	bu(a1*2+1,mid+1,r);
	te[a1]=max(te[a1*2],te[a1*2+1]);
	return ;
}//l~r建树节点a1
void ci(int a1,int l,int r,int x,int y,int v){
	if(l>=x&&r<=y){
		alz(a1,v);
		return ;
	}
	int mid=(l+r)/2;
	dow(a1);
	if(x<=mid){
		ci(a1*2,l,mid,x,y,v);
	}
	if(mid+1<=y){
		ci(a1*2+1,mid+1,r,x,y,v);
	}
	te[a1]=max(te[a1*2],te[a1*2+1]);
	return ;
}//x~y区间加v至l~r区间a1点
long long co(int a1,int l,int r,int x,int y){
	if(x<=l&&r<=y){
		return te[a1];
	}
	int mid=(l+r)/2;
	long long dbdb=-1e18-7;
	dow(a1);
	if(mid>=x){
		dbdb=max(dbdb,co(a1*2,l,mid,x,y));
	}
	if(mid+1<=y){
		dbdb=max(dbdb,co(a1*2+1,mid+1,r,x,y));
	}
    te[a1]=max(te[a1*2],te[a1*2+1]);
	return dbdb;
}//x~y区间问至l~r区间a1点	
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
    bu(1,1,n);
	for(int i=1;i<=m;i++){
		cin>>aa[i].opt;
        aa[i].i=i;
		if(aa[i].opt==1){
			cin>>aa[i].t>>aa[i].l>>aa[i].r>>aa[i].k;
            //lp[++lp[0]]=aa[i].t;
		}
		else if(aa[i].opt==2){
			cin>>aa[i].t>>aa[i].l>>aa[i].r;
            df++;
            //lp[++lp[0]]=aa[i].t;
		}
		else{
			cin>>aa[i].t>>aa[i].l>>aa[i].r;
            //lp[++lp[0]]=aa[i].t;
            //lp[++lp[0]]=aa[i].l;
            //lp[++lp[0]]=aa[i].r;
		}
	}
 //    sort(lp+1,lp+lp[0]+1);
 //    for(int i=1;i<=lp[0];i++){
 //        mp[lp[i]]=i;
 //    }
	// for(int i=1;i<=m;i++){
	// 	if(aa[i].opt==1){
	// 		aa[i].t=mp[aa[i].t];
	// 	}
	// 	else if(aa[i].opt==2){
	// 		aa[i].t=mp[aa[i].t];
	// 	}
	// 	else{
	// 		aa[i].t=mp[aa[i].t];
 //            aa[i].l=mp[aa[i].l];
 //            aa[i].r=mp[aa[i].r];
	// 	}
	// }    
    sort(aa+1,aa+m+1,cmp2);
    df=0;
    for(int i=m;i>=1;i--){
        cf2[i]=cf2[i+1]+cf[i];
        if(aa[i].opt==3&&cf2[i]<=0&&i!=1){
            long long l=1,r=i-1,md=i;
            while(l<=r){
                long long mid=(l+r)/2;
                if(aa[mid].t>=aa[i].l){
                    md=min(md,mid);
                    r=mid-1;
                }
                else{
                    l=mid+1;
                }
            }
            l=1;
            r=i-1;
            long long md2=0;
            while(l<=r){
                long long mid=(l+r)/2;
                if(aa[mid].t<=aa[i].r){
                    md2=max(md2,mid);
                    l=mid+1;
                }
                else{
                    r=mid-1;
                }
            }
            if(md<=md2){
                cf[md2]++;
                cf[md-1]--;                
            }
        }
        else if(aa[i].opt==2&&cf2[i]<=0){
            df++;
        }
    }
    //sort(aa+1,aa+m+1,cmp2);
    cout<<df<<endl;
	for(int i=1;i<=m;i++){
		if(aa[i].opt==1&&cf2[i]<=0){
			ci(1,1,n,aa[i].l,aa[i].r,aa[i].k);
		}
		else if(aa[i].opt==2&&cf2[i]<=0){
			cout<<co(1,1,n,aa[i].l,aa[i].r)<<endl;
		}
	}
	return 0;
}

posted @ 2025-10-08 07:52  bz02_2023f2  阅读(2)  评论(0)    收藏  举报  来源