SXOI2016最大值

70分算法+30分打表

#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define lc k<<1
#define rc k<<1|1
#define EF if(ch==EOF) return x;
using namespace std;
const int N=1e5+5;
const int inf=2e9;
typedef long long ll;
int n,Q,ans,a[N],mx[N];
ll sum[N<<2];bool tag[N<<2];
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;EF;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
void build(int k,int l,int r){
    if(l==r){
        sum[k]=mx[l];
        return ;
    }
    int mid=l+r>>1;
    build(lc,l,mid);
    build(rc,mid+1,r);
    sum[k]=sum[lc]+sum[rc];
}
void pushdown(int k,int l,int r){
    if(!tag[k]||l==r) return ;
    int mid=l+r>>1;
    sum[lc]=sum[k]/(r-l+1)*(mid-l+1);
    sum[rc]=sum[k]/(r-l+1)*(r-mid);
    tag[lc]=tag[rc]=1;tag[k]=0;
}
void change(int k,int l,int r,int x,int y,int v){
    if(l==x&&r==y){
        sum[k]=1LL*(r-l+1)*v;
        tag[k]=1;
        return ;
    }
    pushdown(k,l,r);
    int mid=l+r>>1;
    if(y<=mid) change(lc,l,mid,x,y,v);
    else if(x>mid) change(rc,mid+1,r,x,y,v);
    else change(lc,l,mid,x,mid,v),change(rc,mid+1,r,mid+1,y,v);
    sum[k]=sum[lc]+sum[rc];
}
ll query(int k,int l,int r,int p){
    if(l==r) return sum[k];
    pushdown(k,l,r);
    int mid=l+r>>1;
    if(p<=mid) return query(lc,l,mid,p);
    else return query(rc,mid+1,r,p);
//    sum[k]=sum[lc]+sum[rc];
}
void ord(){
    int Max=-inf;ans=0;
    for(int j=1;j<=n;j++){
        Max=max(Max,a[j]);
        ans+=Max;
    }
    printf("%d\n",ans);
    for(int i=1,x,y;i<=Q;i++){
        x=read();y=read();
        a[x]+=y;
        int Max=-inf;ans=0;
        for(int j=1;j<=n;j++){
            Max=max(Max,a[j]);
            ans+=Max;
        }
        printf("%d\n",ans);
    }
}
int main(){
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();Q=read();
    if(n<=2000){
        ord();
        return 0;
    }
    mx[0]=-inf;
    for(int i=1;i<=n;i++) mx[i]=max(mx[i-1],a[i]);
    build(1,1,n);printf("%I64d\n",sum[1]);
    for(int i=1,x,y;i<=Q;i++){
        x=read();y=read();
        a[x]+=y;
        int l=x,r=n,pos=0;
        while(l<=r){
            int mid=l+r>>1;
            if(query(1,1,n,mid)<a[x]) l=mid+1,pos=mid;
            else r=mid-1;
        }
        if(pos) change(1,1,n,x,pos,a[x]);
        printf("%I64d\n",sum[1]);
    }
    return 0;
}
时间: 2024-10-06 03:03:13

SXOI2016最大值的相关文章

【Oracle】oracle取最大值和最小值的几个方法汇总

(1)oracle使用keep分析函数取最值记录 -- 取工资sal最大的雇员姓名及其工资,以及工资sal最少的雇员姓名及其工资 select deptno, empno, ename, sal, max(ename) keep(dense_rank FIRST order by sal) over (partition by deptno) as min_sal_man, max(sal) keep(dense_rank FIRST order by sal) over (partition

AD域控制器 修改查询记录最大值1000的限制

作为一个AD管理员来说,我们AD计算机管理工具管理LDAP服务是很常见的,但是如果我们组织内的用户比较多的话,就会遇到一个问题呢,通过计算机管理工具搜索所有用户或者某个OU下用户的时候就会发现出现提示信息,提示最大可以显示1000个用户,如果想显示更多的用户需要增加参数或者修改配置等.我们可以通过以下方式进行修改. 开始 -> 运行 -> cmd 输入:  ntdsutil 2. 输入: ldap policies 3. 输入: connections 4. 连接域: connect to d

java实现求一个数组里最大值和最小值之前缺省的数的算法

问题描述: 求一个数组里最大值和最小值之间缺省的数,例如 int arrDemo = {1, 3, 7};  那么就要输出最小值1和最大值7之间缺少的数字2,4,5,6 代码如下,有更好的思路欢迎大家在评论区留言讨论 1 package test; 2 3 public class Test { 4 5 static int[] array = { 6 -10,0,3,3,9 7 }; 8 9 private static void printEmptyItems(int[] array) {

求不相邻金币相加和的最大值--动态规划1

求不相邻金币相加和的最大值. 输入n个金币的金币面值(正数自定义),求这些金币不相邻和的最大值. 动态规划问题1 设f(n)为第n个金币数的最大值,f(0)=0,f(1)=a[1],输入的数组从下标为1开始. f(n)=max{a[n]+f(n-2),f(n-1)}. 代码如下: import java.util.Scanner; public class Jin_bi_zui_da_zhi { public static void main(String[] args) { Scanner s

选择问题,自定义k=N/2为最大值!

方法: k之前的先排序,最大值给k. 之后的逐个比较,大于k直接覆盖,否则k不变. 代码:      package com.Edward.suanfa; import java.util.Random; class getmax{ int getmax_(int a[],int k){//数组a[],k为指定最大值 int max=a[0]; int temp; int len=a.length-1; for(int i=0;i<=k;i++){ if(max>a[i]){ temp=a[i

在一个SQL Server表中的多个列找出最大值

在一个SQL Server表中一行的多个列找出最大值 有时候我们需要从多个相同的列里(这些列的数据类型相同)找出最大的那个值,并显示 这里给出一个例子 IF (OBJECT_ID('tempdb..##TestTable') IS NOT NULL) DROP TABLE ##TestTable CREATE TABLE ##TestTable ( ID INT IDENTITY(1,1) PRIMARY KEY, Name NVARCHAR(40), UpdateByApp1Date DATE

树状数组求区间最大值

------  一直用 线段树 求区间最大值,想换种思路,用树状数组试试,肯定是可以的. 首先要对 树状数组的每个 i 所管理的区间有一定的理解.详见上篇博客: 树状数组(BIT)

题目1191:矩阵最大值

题目描述: 编写一个程序输入一个mXn的矩阵存储并输出,并且求出每行的最大值和每行的总和. 要求把每行总和放入每行最大值的位置,如果有多个最大值,取下标值最小的那一个作为最大值. 最后将结果矩阵输出. 输入: 输入的第一行包括两个整数m和n(1<=m,n<=100),分别代表矩阵的行和列的维数. 接下来的m行每行有n个数,代表矩阵的元素. 输出: 可能有多组测试数据,对于每组数据,输出按题目要求执行后的矩阵. 样例输入: 3 3 1 1 1 1 1 1 1 1 1 3 3 3 2 3 2 3

写一个方法求数组中的最大值,最小值,总和以及平均值。

class Program { /// <summary> /// 求数组中的最大值,最小值,总和以及平均值. /// </summary> /// <param name="nums">输入一个数组</param> /// <returns>返回一个新的数组(max,min,sum,avg)</returns> public static int[] GetMaxMinSumAvg(int[] nums) { i