【UOJ 519】ycw的成绩表

题目背景

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;
}

 

转载于:https://www.cnblogs.com/wuhu-JJJ/p/11216162.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值