UOJ 519ycw的成绩表

Posted wuhu-jjj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UOJ 519ycw的成绩表相关的知识,希望对你有一定的参考价值。

题目背景

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;

 

以上是关于UOJ 519ycw的成绩表的主要内容,如果未能解决你的问题,请参考以下文章

SQL多个表联合查询优化的问题

mysql有一张成绩表(姓名)(班级)(成绩)三个字段,查出不同班级的成绩前三名的学生的分数

mysql数据库面试题(学生表_课程表_成绩表_教师表)

设计表:多张表存储学生成绩及各种信息

怎样编写SQL语句求平均成绩

SQL:选课表(学号,课程号,成绩),现要查询成绩最高的三个学生的学号、课程号和成绩,包括并列情况