习题:服务器需求(线段树)

题目

传送门

思路

题目中最关键的一句话是m天可以不连续
很容易推出最少需要的服务器一定与\(\max_{i=1}^{n}a_i\)有关
且至少为\(\max_{i=1}^{n}a_i\),有了这个之后,
我们考虑如何维护最大值,
笔者过于菜,选择了线段树
有一些大犇选择了multiset
另外注意输入输出。。。

代码

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
#define int long long
void read(int &x)
{
    x=0;
    int f=1;
    char c=getchar();
    while('0'>c||c>'9')
    {
        if(c=='-')
            f=-1;
        c=getchar();
    }
    while('0'<=c&&c<='9')
    {
        x=(x<<3)+(x<<1)+c-'0';
        c=getchar();
    }
    x*=f;
}
void write(int x)
{
    if(x<10)
        putchar(x+'0');
    else
    {
        write(x/10);
        putchar(x%10+'0');
    }
}
struct node
{
    int l;
    int r;
    int maxx;
}tre[1600005];
int n,m,q;
int s;
int p,v;
void build(int l,int r,int k)
{
    tre[k].l=l;
    tre[k].r=r;
    if(l==r)
    {
        read(tre[k].maxx);
        s+=tre[k].maxx;
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,k<<1);
    build(mid+1,r,k<<1|1);
    tre[k].maxx=max(tre[k<<1].maxx,tre[k<<1|1].maxx);
}
void change(int k)
{
    if(tre[k].l==tre[k].r)
    {
        s-=tre[k].maxx;
        tre[k].maxx=v;
        s+=tre[k].maxx;
        return;
    }
    if(tre[k<<1].l<=p&&p<=tre[k<<1].r)
        change(k<<1);
    else
        change(k<<1|1);
    tre[k].maxx=max(tre[k<<1].maxx,tre[k<<1|1].maxx);
}
void pr()
{
    if(tre[1].maxx*m>=s)
    {
        write(tre[1].maxx);
        putchar('\n');
    }
    else
    {
        int t;
        t=s-tre[1].maxx*m;
        if(t%m==0)
        {
            write(t/m+tre[1].maxx);
            putchar('\n');
        }
        else
        {
            write(t/m+1+tre[1].maxx);
            putchar('\n');
        }
    }
}
signed main()
{
    read(n);
    read(m);
    read(q);
    build(1,n,1);
    pr();
    for(int i=1;i<=q;i++)
    {
        read(p);
        read(v);
        change(1);
        pr();
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/loney-s/p/11782548.html