题目背景
wwh是芜湖一中的一名程序员,有一天,他有幸被ycw的找去。。。
Ycw有n张数学考试卷。
题目描述
ycw的问题是这样的:
ycw有一大堆的考试卷,一共n张,这些考试卷被他排成一行,每次考试都有一个预期成绩。
ycw一共有m个问题:
1 x k 将第x次考试的预期成绩加上为k(比如,ycw重考一遍)
2 x y k 将第x到y次考试的预期成绩都加上k(比如,ycw疯狂刷题)
3 x y 求第x到y次考试的预期成绩最大值。
4 x y 求第x到y次考试的预期成绩最小值。
ycw不想被老师和家长找,也不想写线段树,于是他找到了wwh。
wwh只会暴力,于是找到了AK了NOI2017的C国的第一OIer,你,来帮他解决这个问题。
输入输出格式
输入格式:
第一行两个数n,m。
第二行n个数,分别表示原来考试的预期成绩
第3~m+2行,表示ycw的问题,格式如题目描述中所述。
输出格式:
每行一个数,表示3,4询问的答案
数据生成器(因为大样例放不下)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int main(){
freopen("flower.in","w",stdout);
int n,m;n=m=200000;
printf("%d %d\n",n,m);
for(int i=1;i<=n;i++){
printf("%d ",rand()+1);
}
printf("\n");
while(m--){
int x;x=rand()%4+1;
if(x==1){
printf("1 %d %d\n",rand()%n+1,rand()+1);
}
else if(x==2){
int l,r;l=rand()%n+1;r=rand()%n+1;
if(r<l) swap(l,r);
printf("2 %d %d %d\n",l,r,rand()+1);
}
else if(x==3){
int l,r;l=rand()%n+1;r=rand()%n+1;
if(r<l) swap(l,r);
printf("3 %d %d\n",l,r);
}
else if(x==4){
int l,r;l=rand()%n+1;r=rand()%n+1;
if(r<l) swap(l,r);
printf("4 %d %d\n",l,r);
}
}
return 0;
}
暴力
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
long long n,m,s[200005];
long long read(){
char ch;long long w,f;w=0;f=1;
ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){w=w*10+ch-'0';ch=getchar();}
return w*f;
}
int main(){
freopen("flower.in","r",stdin);
freopen("flower1.out","w",stdout);
n=read();m=read();
for(int i=1;i<=n;i++)
s[i]=read();
long long a,x,y,z;
while(m--){
a=read();
if(a==1){
x=read();z=read();s[x]+=z;
}
else if(a==2){
x=read();y=read();z=read();
for(long long i=x;i<=y;i++)
s[i]+=z;
}
else if(a==3){
x=read();y=read();long long ans=-1e15;
for(long long i=x;i<=y;i++)
ans=max(ans,s[i]);
printf("%lld\n",ans);
}
else{
x=read();y=read();long long ans=1e15;
for(long long i=x;i<=y;i++)
ans=min(ans,s[i]);
printf("%lld\n",ans);
}
}
}
说明
100%数据保证:n , m<=200,000,1<=x , y<=n,|k|<=10^9
题解:半小时不到打完程序,修改了快1个小时,心态还没崩我觉得我也挺厉害的,
L打成l,R打成r,空间没*4,PushDown特判多了等等各种问题层出不穷。醉了
#include<bits/stdc++.h> #include<iostream> #include<algorithm> #include<queue> #include<cmath> #include<cstring> #include<cstdlib> #include<cstdio> using namespace std; typedef long long ll; const int N=200002; ll x,y,mx[N*4],mn[N*4],Add[N*4],n,mt,op,z,a[N]; long long get(){ char ch;long long w,f;w=0;f=1; ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9'){w=w*10+ch-'0';ch=getchar();} return w*f; } ll maxx(ll p,ll q){ if(p>q) return p; else return q; } ll minn(ll p,ll q){ if(p<q) return p; else return q; } void PushDown(int rt,int ln,int rn){ //if(ln==rn){ //printf("%lld %lld\n",ln,rt); //return; //} if(Add[rt]){ Add[rt*2]+=Add[rt]; Add[rt*2+1]+=Add[rt]; mx[rt*2]+=Add[rt]; mx[rt*2+1]+=Add[rt]; mn[rt*2]+=Add[rt]; mn[rt*2+1]+=Add[rt]; Add[rt]=0; } } void PushUp(ll rt){ mx[rt]=maxx(mx[rt*2],mx[rt*2+1]); mn[rt]=minn(mn[rt*2],mn[rt*2+1]); } void Build(ll l,ll r,ll rt){ if(l==r){ mx[rt]=a[l]; mn[rt]=a[l]; return; } ll m=(l+r)/2; Build(l,m,rt*2); Build(m+1,r,rt*2+1); PushUp(rt); } ll workMN(ll L,ll R,ll l,ll r,ll rt){ if(L<=l && r<=R) return mn[rt]; ll m=(l+r)/2; PushDown(rt,m-l+1,r-m); ll ANS=1e15; if(L<=m) ANS=minn(ANS,workMN(L,R,l,m,rt*2)); if(R>m) ANS=minn(ANS,workMN(L,R,m+1,r,rt*2+1)); return ANS; } ll workMX(ll L,ll R,ll l,ll r,ll rt){ if(L<=l && r<=R) return mx[rt]; ll m=(l+r)/2; PushDown(rt,m-l+1,r-m); ll ANS=-1e15; if(L<=m) ANS=maxx(ANS,workMX(L,R,l,m,rt*2)); if(R>m) ANS=maxx(ANS,workMX(L,R,m+1,r,rt*2+1)); return ANS; } void Update(ll L,ll R,ll C,ll l,ll r,ll rt){ if(L <= l && r <= R){ Add[rt]+=C; mx[rt]+=C; mn[rt]+=C; return ; } ll m=(l+r)/2; PushDown(rt,m-l+1,r-m); if(L <= m) Update(L,R,C,l,m,rt*2); if(R > m) Update(L,R,C,m+1,r,rt*2+1); PushUp(rt); } int main(){ n=get(); mt=get(); for(int i=1;i<=n;i++) a[i]=get(); Build(1,n,1); while(mt--){ op=get(); if(op==1){ x=get(); y=get(); Update(x,x,y,1,n,1); } else if(op==2){ x=get(); y=get(); z=get(); Update(x,y,z,1,n,1); } else if(op==3){ x=get(); y=get(); printf("%lld\n",workMX(x,y,1,n,1)); } else if(op==4){ x=get(); y=get(); printf("%lld\n",workMN(x,y,1,n,1)); } } return 0; }