CF992E Nastya and King-Shamans 解题报告

CF992E Nastya and King-Shamans

题意翻译

给定一个序列 \(a_i\),记其前缀和序列为 \(s_i\),有 \(q\) 个询问,每次单点修改,询问是否存在一个 \(i\) 满足 \(a_i=s_{i-1}\),有多解输出任意一个,无解输出 \(-1\)

输入输出格式

输入格式:

The first line contains two integers \(n\) and \(q\)

The second line contains n n integers \(a_{1},...,a_{n}\),where \(a_{i}\)is the magic power of the \(i\)-th shaman.

After that \(q\) lines follow, the \(i\) -th of them contains two integers \(p_{i}\) and \(x_{i}\)that mean that the new power of the \(p_{i}\).

输出格式:
Print \(q\) lines, the \(i\) -th of them should contain \(-1\) , if after the \(i\) -th change there are no shaman-kings, and otherwise a single integer \(j\) , where \(j\) is an index of some king-shaman after the \(i\) -th change.

If there are multiple king-shamans after each change, print the index of any of them.

数据范围

\(1 \le n,q \le 10^5,0 \le a_i \le 10^9,1 \le p_i \le n,0 \le x_i \le 10^9\)


注意一下数据范围,发现都是正整数。

所以前缀和按位置是不降的。

考虑一个暴力,找到每个\(a_i \ge s_{i-1}\)的位置,然后检查它是否合法。

考虑这样的一个位置最多有多少个,发现不超过\(log 10^9\),所以这个暴力复杂度是对的。

至于实现,可以线段树维护\(a_i-s_{i-1}\)的最大值,支持区间加全局查询就行了。


Code:

#include <cstdio>
#define ll long long
#define ls id<<1
#define rs id<<1|1
const int N=2e5+10;
ll max(ll x,ll y){return x>y?x:y;}
ll mx[N<<2],a[N],f[N],tag[N<<2],x;
int n,q;
void updata(int id){mx[id]=max(mx[ls],mx[rs]);}
void build(int id,int l,int r)
{
    if(l==r)
    {
        mx[id]=a[l]-f[l-1];
        return;
    }
    int mid=l+r>>1;
    build(ls,l,mid),build(rs,mid+1,r);
    updata(id);
}
void pushdown(int id)
{
    if(tag[id])
    {
        tag[ls]+=tag[id],tag[rs]+=tag[id];
        mx[ls]+=tag[id],mx[rs]+=tag[id];
        tag[id]=0;
    }
}
void change1(int id,int l,int r,int p,ll d)
{
    if(l==r)
    {
        mx[id]+=d;
        return;
    }
    pushdown(id);
    int mid=l+r>>1;
    if(p<=mid) change1(ls,l,mid,p,d);
    else change1(rs,mid+1,r,p,d);
    updata(id);
}
void change0(int id,int L,int R,int l,int r,ll d)
{
    if(l>r) return;
    if(l==L&&r==R)
    {
        tag[id]+=d,mx[id]+=d;
        return;
    }
    pushdown(id);
    int Mid=L+R>>1;
    if(r<=Mid) change0(ls,L,Mid,l,r,d);
    else if(l>Mid) change0(rs,Mid+1,R,l,r,d);
    else change0(ls,L,Mid,l,Mid,d),change0(rs,Mid+1,R,Mid+1,r,d);
}
int query(int id,int l,int r)
{
    if(l==r) return mx[id]==0?l:-1;
    if(mx[id]<0) return -1;
    pushdown(id);
    int mid=l+r>>1;
    int la=query(ls,l,mid);
    return ~la?la:query(rs,mid+1,r);
}
int main()
{
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++) scanf("%lld",a+i),f[i]=f[i-1]+a[i];
    build(1,1,n);
    for(int p,i=1;i<=q;i++)
    {
        scanf("%d%lld",&p,&x);
        change0(1,1,n,p+1,n,a[p]-x);
        change1(1,1,n,p,x-a[p]);
        a[p]=x;
        printf("%d\n",query(1,1,n));
    }
    return 0;
}

2018.10.9

posted @ 2018-10-09 12:55  露迭月  阅读(596)  评论(0编辑  收藏  举报