pushup应该对了的蒟蒻但只有9分·(样例已过(简单易懂)
查看原帖
pushup应该对了的蒟蒻但只有9分·(样例已过(简单易懂)
709447
tx774楼主2023/7/29 14:11
#include<bits/stdc++.h>
using namespace std;
#define int long long
/*
在太阳西斜的这个世界里,置身天上之森。
等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去、逐渐消逝的未来。
我回来了,纵使日薄西山,即便看不到未来,此时此刻的光辉,盼君勿忘。
————世界上最幸福的女孩
*/
const int N=1e5+5;
int n,Q;
int a[N];

struct menber{
    int l,r;
    //s: 表示按照题目要求将区间清零要多少次操作
    //01表示这个区间的左端点不用管,即 [l,r)
    //10表示右端点不用管 ,即 (l,r]
    //11表示两个端点都不用管,即 (l,r)
    //00表示都要管,即 [l,r]
    //cl:表示 [l,r] 这个区间在四种情况下左端点有没有被选
    //cr:表示 [l,r] 这个区间在四种情况下右端点有没有被选
    int s10,s00,s01,s11;
    int cl11,cl00,cl10,cl01;
    int cr11,cr00,cr10,cr01;
};menber node[4*N];

void pushup(int o)
{
    int mid=(node[o].l+node[o].r)/2;
    int ls=o<<1;
    int rs=o<<1|1;
    //00
    //左儿子右端点被选 00 [l,r]且右儿子左端点被选 00 [l,r]
    if(node[ls].cr00 && node[rs].cl00)
    {
        if(a[mid]>=a[mid+1])
        {
            node[o].s00=node[ls].s00+node[rs].s10;
            node[o].cl00=node[ls].cl00;node[o].cr00=node[rs].cr10;
        }
        else
        {
            node[o].s00=node[ls].s01+node[rs].s00;
            node[o].cl00=node[ls].cl01;node[o].cr00=node[rs].cr00;
        }
    }
    else
    {
        node[o].s00=node[ls].s00+node[rs].s00;
        node[o].cl00=node[ls].cr00;node[o].cr00=node[rs].cr00;
    }
    //10
    //左儿子右端点被选 10 (l,r]且 右儿子左端点被选 00 [l,r]
    if(node[ls].cr10 && node[rs].cl00)
    {
        if(a[mid]>=a[mid+1])
        {
            node[o].s10=node[ls].s10+node[rs].s10;
           /*node[o].cl10=node[ls].cl10;*/node[o].cr10=node[rs].cr10;
        }
        else
        {
            node[o].s10=node[ls].s11+node[rs].s00;
            /*node[o].cl10=node[ls].cl11;*/node[o].cr10=node[rs].cr00;
        }
    }
    else
    {
        node[o].s10=node[ls].s10+node[rs].s00;
        /*node[o].cl10=node[ls].cr10;*/node[o].cr10=node[rs].cr00;
    }
    //01
    //左儿子右端点被选 00 [l,r]且 右儿子左端点被选 01 [l,r)
    if(node[ls].cr00 && node[rs].cl01)
    {
        if(a[mid]>=a[mid+1])
        {
            node[o].s01=node[ls].s00+node[rs].s11;
            node[o].cl01=node[ls].cl00;//node[o].cr01=node[rs].cr11;
        }
        else
        {
            node[o].s01=node[ls].s01+node[rs].s01;
            node[o].cl01=node[ls].cl01;//node[o].cr01=node[rs].cr01;
        }
    }
    else
    {
        node[o].s01=node[ls].s00+node[rs].s01;
        node[o].cl01=node[ls].cr00;//node[o].cr01=node[rs].cr01;
    }
    //11
    //左儿子右端点被选 10 (l,r]且 右儿子左端点被选 01 [l,r)
    if(node[ls].cr10 && node[rs].cl01)
    {
        if(a[mid]>=a[mid+1])
        {
            node[o].s11=node[ls].s10+node[rs].s11;
            //node[o].cl11=node[ls].cl10;node[o].cr11=node[rs].cr11;
        }
        else
        {
            node[o].s11=node[ls].s11+node[rs].s01;
            //node[o].cl11=node[ls].cl11;node[o].cr11=node[rs].cr01;
        }
    }
    else
    {
        node[o].s11=node[ls].s10+node[rs].s01;
        //node[o].cl11=node[ls].cr10;node[o].cr11=node[rs].cr01;
    }
}

void build_tree(int o, int l, int r)
{
    node[o].l=l;
    node[o].r=r;
    if(l==r)
    {
        node[o].s00=a[l];
        node[o].cl00=1;
        node[o].cr00=1;
        return;
    }
    int mid=(l+r)/2;
    build_tree(o<<1,l,mid);
	build_tree(o<<1|1,mid+1,r);
    pushup(o);
}

void update(int o,int x)
{
    if (node[o].l == node[o].r)
    {
        node[o].s00=a[node[o].l];
        return;
    }
    int mid=(node[o].l+node[o].r)/2;
    if(x<=mid)  update(o<<1,x);
    else  update(o<<1|1,x);
    pushup(o);
}

void service()
{
    int x,y;
    int ans=0;
    cin>>x>>y;
    a[x]=y;
    update(1,x);
    cout<<node[1].s00<<endl;
}

signed main()
{
    cin>>n;
    for(int i=1;i<=n;++i)
        cin>>a[i];
    build_tree(1, 1, n);
    cin>>Q;
    while(Q--)
        service();
    return 0;
}

2023/7/29 14:11
加载中...