Noi.ac #51题解

Posted lgj-lgj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Noi.ac #51题解相关的知识,希望对你有一定的参考价值。

题目链接

(Solution:)

容易看出是一道平衡树的题(这里我们用(fhq-Treap)维护)
但是由于(A)操作是全局修改,所以我们甚至不需要维护一个延迟标记,只需在全局记录两个标记即可

(Code:)

#include<bits/stdc++.h>
using namespace std;
namespace my_std
{
    typedef long long ll;
    #define fr(i,x,y) for(ll i=(x);i<=(y);i++)
    inline ll read()
    {
        ll sum=0,f=1;
        char ch=0;
        while(!isdigit(ch))
        {
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            sum=(sum<<1)+(sum<<3)+(ch^48);
            ch=getchar();
        }
        return sum*f;
    }
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-');
            x=-x;
        }
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
}
using namespace my_std;
const ll N=5e5+50;
ll n,m,rt,cnt,sum,tg1,tg2=1;
char opt[10];
struct node
{
    ll l,r,key,v,val,sz;
}fhq[N];
inline void pushup(ll p)
{
    fhq[p].sz=fhq[fhq[p].l].sz+fhq[fhq[p].r].sz+1;
}
inline ll newnode(ll val,ll v)
{
    cnt++;
    fhq[cnt].val=val;
    fhq[cnt].v=v;
    fhq[cnt].key=rand();
    fhq[cnt].sz=1;
    return cnt;
}
void split(ll p,ll k,ll &x,ll &y)
{
    if(!p)
    {
        x=y=0;
        return;
    }
    if(fhq[p].val<=k)
    {
        x=p;
        split(fhq[p].r,k,fhq[p].r,y);
    }
    else
    {
        y=p;
        split(fhq[p].l,k,x,fhq[p].l);
    }
    pushup(p);
}
ll merge(ll a,ll b)
{
    if(!a||!b) return a+b;
    if(fhq[a].key<fhq[b].key)
    {
        fhq[a].r=merge(fhq[a].r,b);
        pushup(a);
        return a;
    }
    else
    {
        fhq[b].l=merge(a,fhq[b].l);
        pushup(b);
        return b;
    }
}
inline int find(ll val)
{
    ll x,y,z;
    split(rt,val-1,x,y);
    split(y,val,y,z);
    rt=merge(merge(x,y),z);
    return (y!=0);
}
inline void update(ll p,ll q)
{
    if(find(p))
    {
        ll x,y,z;
        split(rt,p-1,x,y);
        split(y,p,y,z);
        sum-=fhq[y].v;
        sum+=q;
        fhq[y].v=q;
        rt=merge(merge(x,y),z);
    }
    else
    {
        ll x,y;
        split(rt,p,x,y);
        sum-=(ll)p*tg2+tg1;
        sum+=q;
        rt=merge(merge(x,newnode(p,q)),y);
    }
}
int main(void)
{
    n=read(),m=read();
    sum=n*(n+1)/2;
    fr(i,1,m)
    {
        scanf("%s",opt);
        if(opt[0]=='A')
        {
            ll p,q;
            p=read(),q=read();
            tg2=p,tg1=q;
            sum=(n*(n+1)/2)*p+q*n;
            rt=0;
        }
        else
        {
            ll x,y;
            x=read(),y=read();
            update(x,y);
        }
        write(sum);
        putchar('
');
    }
    return 0;
}

以上是关于Noi.ac #51题解的主要内容,如果未能解决你的问题,请参考以下文章

[noi.ac省选模拟赛]第12场题解集合

noi,ac第五场部分题解 By cellur925

noi.ac #241 distance

noi.ac #39

noi.ac #712 练级

noi.ac #525 神树的权值