社区讨论
吉司机线段树TLE 80pts 求调
P6242【模板】线段树 3(区间最值操作、区间历史最值)参与者 3已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @lwkaw9e1
- 此快照首次捕获于
- 2024/05/24 14:28 2 年前
- 此快照最后确认于
- 2024/05/24 18:16 2 年前
CPP
#include<bits/stdc++.h>
namespace Fread{
const long long SIZE=1<<21;
char buf[SIZE],*S,*T;
inline char getchar(){
if (S==T){
T=(S=buf)+fread(buf,1,SIZE,stdin);
if(S==T){
return '\n';
}
}
return *S++;
}
}
namespace Fwrite{
const long long SIZE=1<<21;
char buf[SIZE],*S=buf,*T=buf+SIZE;
inline void flush(){
fwrite(buf,1,S-buf,stdout);
S=buf;
}
inline void putchar(char c){
*S++=c;
if(S==T){
flush();
}
}
struct NTR{
~NTR(){
flush();
}
}ztr;
}
#ifdef ONLINE_JUDGE
#define getchar Fread::getchar
#define putchar Fwrite::putchar
#endif
namespace Fastio{
struct Reader{
template<typename T>
Reader& operator>>(T& x){
char c=getchar();
T f=1;
while (c<'0'||c>'9'){
if (c=='-') f=-1;
c=getchar();
}
x=0;
while (c>='0'&&c<='9'){
x=x*10+(c-'0');
c=getchar();
}
x*=f;
return *this;
}
Reader& operator>>(char& c){
c=getchar();
while (c==' '||c=='\n'){
c=getchar();
}
return *this;
}
Reader& operator>>(char* str){
long long len=0;
char c=getchar();
while (c==' '||c=='\n'){
c=getchar();
}
while (c!=' '&&c!='\n'&&c!='\r'){
str[len++]=c;
c=getchar();
}
str[len]='\0';
return *this;
}
Reader(){}
}cin;
const char endl='\n';
struct Writer{
template<typename T>
Writer&operator<<(T x){
if(x==0){
putchar('0');
return *this;
}
if(x<0){
putchar('-');
x=-x;
}
static long long sta[45];
long long top=0;
while(x){
sta[++top]=x%10;
x/=10;
}
while(top){
putchar(sta[top]+'0');
--top;
}
return *this;
}
Writer& operator<<(char c){
putchar(c);
return *this;
}
Writer& operator<<(char* str){
long long cur=0;
while(str[cur]){
putchar(str[cur++]);
}
return *this;
}
Writer& operator<<(const char* str){
long long cur=0;
while(str[cur]){
putchar(str[cur++]);
}
return *this;
}
Writer(){}
}cout;
}
#define cin Fastio::cin
#define cout Fastio::cout
#define endl Fastio::endl
using namespace std;
int n,m,a[520010],op,l,r,k,v;
struct edge{
int lef,rig;
int Max,hisMax,nxtMax,Maxnum;
long long sum=0;
int lz1,hislz1,lz2,hislz2;
}tr[2200010];
inline void update(int id){
int lefson=(id<<1),rigson=(id<<1|1);
tr[id].sum=tr[lefson].sum+tr[rigson].sum;
tr[id].hisMax=max(tr[lefson].hisMax,tr[rigson].hisMax);
if(tr[lefson].Max==tr[rigson].Max){
tr[id].Max=tr[lefson].Max;
tr[id].nxtMax=max(tr[lefson].nxtMax,tr[rigson].Max);
tr[id].Maxnum=tr[lefson].Maxnum+tr[rigson].Maxnum;
}
else if(tr[lefson].Max>tr[rigson].Max){
tr[id].Max=tr[lefson].Max;
tr[id].nxtMax=max(tr[lefson].nxtMax,tr[rigson].Max);
tr[id].Maxnum=tr[lefson].Maxnum;
}
else {
tr[id].Max=tr[rigson].Max;
tr[id].nxtMax=max(tr[lefson].Max,tr[rigson].nxtMax);
tr[id].Maxnum=tr[rigson].Maxnum;
}
}
inline void build(int id,int lef,int rig){
tr[id].lef=lef;tr[id].rig=rig;
if(lef==rig){
tr[id].sum=tr[id].hisMax=tr[id].Max=a[lef];
tr[id].nxtMax=INT_MIN;tr[id].Maxnum=1;
return;
}
build(id<<1,lef,(lef+rig>>1));
build(id<<1|1,(lef+rig>>1)+1,rig);
update(id);
}
inline void fix(int id,int fixnum1,int hisfixnum1,int fixnum2,int hisfixnum2){
tr[id].sum+=1ll*fixnum1*tr[id].Maxnum+1ll*fixnum2*(tr[id].rig-tr[id].lef+1-tr[id].Maxnum);
tr[id].hisMax=max(tr[id].hisMax,tr[id].Max+hisfixnum1);
tr[id].hislz1=max(tr[id].hislz1,tr[id].lz1+hisfixnum1);
tr[id].hislz2=max(tr[id].hislz2,tr[id].lz2+hisfixnum2);
tr[id].Max+=fixnum1;tr[id].lz1+=fixnum1;tr[id].lz2+=fixnum2;
if(tr[id].nxtMax!=INT_MIN)tr[id].nxtMax+=fixnum2;
}
inline void pushdown(int id){
int lefson=(id<<1),rigson=(id<<1|1);
int flag=max(tr[lefson].Max,tr[rigson].Max);
if(tr[lefson].Max==flag)fix(lefson,tr[id].lz1,tr[id].hislz1,tr[id].lz2,tr[id].hislz2);
else fix(lefson,tr[id].lz2,tr[id].hislz2,tr[id].lz2,tr[id].hislz2);
if(tr[rigson].Max==flag)fix(rigson,tr[id].lz1,tr[id].hislz1,tr[id].lz2,tr[id].hislz2);
else fix(rigson,tr[id].lz2,tr[id].hislz2,tr[id].lz2,tr[id].hislz2);
tr[id].lz1=tr[id].lz2=tr[id].hislz1=tr[id].hislz2=0;
}
inline void modify1(int id,int lef,int rig,int fixnum){
if(tr[id].lef>rig||tr[id].rig<lef)return;
if(tr[id].lef>=lef&&tr[id].rig<=rig){
fix(id,fixnum,fixnum,fixnum,fixnum);
return;
}
pushdown(id);
modify1(id<<1,lef,rig,fixnum);modify1(id<<1|1,lef,rig,fixnum);
update(id);
}
inline void modify2(int id,int lef,int rig,int fixnum){
if(tr[id].lef>rig||tr[id].rig<lef||fixnum>=tr[id].Max)return;
if(tr[id].lef>=lef&&tr[id].rig<=rig&&fixnum>tr[id].nxtMax){
fix(id,fixnum-tr[id].Max,fixnum-tr[id].Max,0,0);
return;
}
pushdown(id);
modify2(id<<1,lef,rig,fixnum);modify2(id<<1|1,lef,rig,fixnum);
update(id);
}
inline long long query1(int id,int lef,int rig){
if(tr[id].lef>rig||tr[id].rig<lef)return 0;
if(tr[id].lef>=lef&&tr[id].rig<=rig)return tr[id].sum;
pushdown(id);
return query1(id<<1,lef,rig)+query1(id<<1|1,lef,rig);
}
inline int query2(int id,int lef,int rig){
if(tr[id].lef>rig||tr[id].rig<lef)return INT_MIN;
if(tr[id].lef>=lef&&tr[id].rig<=rig)return tr[id].Max;
pushdown(id);
return max(query2(id<<1,lef,rig),query2(id<<1|1,lef,rig));
}
inline int query3(int id,int lef,int rig){
if(tr[id].lef>rig||tr[id].rig<lef)return INT_MIN;
if(tr[id].lef>=lef&&tr[id].rig<=rig)return tr[id].hisMax;
pushdown(id);
return max(query3(id<<1,lef,rig),query3(id<<1|1,lef,rig));
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
build(1,1,n);
while(m--){
cin>>op>>l>>r;
switch(op){
case 1:
cin>>k;modify1(1,l,r,k);
break;
case 2:
cin>>v;modify2(1,l,r,v);
break;
case 3:
cout<<query1(1,l,r)<<"\n";
break;
case 4:
cout<<query2(1,l,r)<<"\n";
break;
case 5:
cout<<query3(1,l,r)<<"\n";
break;
}
}
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...