自学内容网 自学内容网

abc371 f

F - Takahashi in Narrow Road
在这里插入图片描述我们可以发现,每次操作后,对于一段变化后的区间,其变为了一段公差为1的等差数列,所以我们如果把每个值减去对应的下标,那么对应的区间变化后,都为一个相同的值,这样就可以使用区间推平,用线段树进行维护即可,然后根据题目信息,每次计算出变化区间的左端点和右端点即可。

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
typedef long long ll;
const int maxv = 4e6 + 5;
typedef pair<ll, ll> pll;
typedef array<int,3> ar;
// #define endl "\n"
int mod=1e9+7;
const int inf=0x3f3f3f3f;

struct node
{
    ll l,r,sum,add;
    #define l(x) tr[x].l
    #define r(x) tr[x].r
    #define sum(x) tr[x].sum
    #define add(x) tr[x].add
}tr[N*4];

int a[N];


void update(int p)
{
    sum(p)=sum(p*2)+sum(p*2+1);
}


void build(int p,int l,int r)
{
    if(l==r){
        tr[p]={l,r,a[l],0};
        return ;
    }
    l(p)=l,r(p)=r;
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    update(p);
}

void pushdown(int p)
{
    if(add(p)){
        sum(p*2)=(r(p*2)-l(p*2)+1)*add(p);
        sum(p*2+1)=(r(p*2+1)-l(p*2+1)+1)*add(p);
        add(p*2)=add(p);
        add(p*2+1)=add(p);
        add(p)=0;
    }
}

void modify(int p,int l,int r,int tag)
{
    if(l<=l(p)&&r(p)<=r){
        add(p)=tag;
        sum(p)=(r(p)-l(p)+1)*tag;
        return ;
    }
    pushdown(p);
    int mid=(l(p)+r(p))/2;
    if(l<=mid) modify(p*2,l,r,tag);
    if(r>mid) modify(p*2+1,l,r,tag);
    update(p);
    
}

ll query(int p,int l,int r)
{
    if(l<=l(p)&&r(p)<=r){
        return sum(p);
    }
    pushdown(p);
    int mid=(l(p)+r(p))/2;
    ll res=0;
    if(l<=mid) res+=query(p*2,l,r);
    if(r>mid) res+=query(p*2+1,l,r);
    return res;
}

void solve()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i],a[i]-=i;
    int q;
    cin>>q;
    auto get=[&](int x,int l,int r)
    {
        int ans=0;
        while(l<=r){
            int mid=(l+r)/2;
            if(query(1,mid,mid)>=x){
                ans=mid,r=mid-1;
            }
            else l=mid+1;
        }
        return ans;
    };
    auto get1=[&](int x,int l,int r)
    {
        int ans=0;
        while(l<=r){
            int mid=(l+r)/2;
            if(query(1,mid,mid)<=x){
                ans=mid,l=mid+1;
            }
            else r=mid-1;
        }
        return ans;
    };
    ll ans=0;
    build(1,1,n);
    while(q--){
        ll x,y;
        cin>>x>>y;
        y-=x;
        ll val=query(1,x,x);
        int l,r;
        if(val<=y){
            l=x,r=get1(y,x,n);

        }
        else{
            l=get(y,1,x),r=x;
        }
        // cout<<val<<" "<<l<<" "<<r<<endl;
        ans+=abs(query(1,l,r)-y*(r-l+1));
        modify(1,l,r,y);
    }
    cout<<ans<<endl;
}


int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
// cin>>t;
while (t--)
{
solve();
}
system("pause");
return 0;
}

原文地址:https://blog.csdn.net/Unlimited_ci/article/details/142826592

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!