题目背景
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
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #define ll long long using namespace std; const int MAXN=1600005,inf=100000000; int n,m,x; ll k,jl[MAXN],u,v; struct cyq{ int l,r; ll ma,mi,tip; }a[MAXN]; void build(int p,int l,int r){ a[p].l=l; a[p].r=r; a[p].ma=-1000*inf; a[p].mi=1000*inf; if(l==r){ a[p].ma=a[p].mi=jl[l]; return; } int mid=(l+r)>>1; build(p*2,l,mid); build(p*2+1,mid+1,r); a[p].ma=max(a[p*2].ma,a[p*2+1].ma); a[p].mi=min(a[p*2].mi,a[p*2+1].mi); } void spread(int p){ if(a[p].tip==0||a[p].l==a[p].r){ return; } a[p*2].ma+=a[p].tip; a[p*2].mi+=a[p].tip; a[p*2+1].ma+=a[p].tip; a[p*2+1].mi+=a[p].tip; a[p*2].tip+=a[p].tip; a[p*2+1].tip+=a[p].tip; a[p].tip=0; } void change(int p){ if(u<=a[p].l && v>=a[p].r){ a[p].ma+=k;a[p].mi+=k; a[p].tip+=k;return; } spread(p); int mid=(a[p].l+a[p].r)>>1; if(u<=mid){ change(p*2); } if(v>mid){ change(p*2+1); } a[p].ma=max(a[p*2].ma,a[p*2+1].ma); a[p].mi=min(a[p*2].mi,a[p*2+1].mi); } ll ask1(int p){ if(u<=a[p].l&&v>=a[p].r){ return a[p].ma; } spread(p); long long ans=-inf*1000; int mid=(a[p].l+a[p].r)>>1; if(u<=mid){ ans=max(ans,ask1(p*2)); } if(v>mid){ ans=max(ans,ask1(p*2+1)); } return ans; } ll ask2(int p){ if(u<=a[p].l && v>=a[p].r){ return a[p].mi; } spread(p); long long ans=inf*1000; int mid=(a[p].l+a[p].r)>>1; if(u<=mid){ ans=min(ans,ask2(p*2)); } if(v>mid){ ans=min(ans,ask2(p*2+1)); } return ans; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%lld",&jl[i]); } build(1,1,n); while(m--){ scanf("%d%lld%lld",&x,&u,&v); if(x==1){ k=v; v=u; change(1); } if(x==2){ scanf("%lld",&k); change(1); } if(x==3){ printf("%lld\n",ask1(1)); } if(x==4){ printf("%lld\n",ask2(1)); } } return 0; }