分块0分求助

P2801 教主的魔法

WydnksqhbD_2 @ 2024-02-03 14:08:01

rt,测试点全 WA。

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N=1e6+5,sq=2e3;
int n,m,len,cnt;
int a[N],b[N],id[N],charge[sq],lpos[sq],rpos[sq];
void mergesort(int left,int right)
{
    if(left==right)return;
    int mid=left+(right-left)/2;
    mergesort(left,mid);mergesort(mid+1,right);
    int i=left,j=mid+1,k=left;
    while(i<=mid&&j<=right)
    {
        if(a[i]<=a[j])b[k++]=a[i++];
        else b[k++]=a[j++];
    }
    while(i<=mid)b[k++]=a[i++];
    while(j<=right)b[k++]=a[j++];
    return;
}
void update(int l,int r,int k)
{
    for(int i=l;i<=min(rpos[id[l]],r);i++)a[i]+=k;
    if(id[l]!=id[r])
    {
        for(int i=lpos[id[r]];i<=r;i++)
            a[i]+=k;
        mergesort(lpos[id[r]],r);
    }
    for(int i=id[l]+1;i<id[r];i++)
        charge[i]+=k;
    return;
}
void query(int l,int r,int k)
{
    int ans=0;
    for(int i=l;i<=min(rpos[id[l]],r);i++)
        ans+=(a[i]+charge[id[i]]<k);
    if(id[l]!=id[r])
        for(int i=lpos[id[r]];i<=r;i++)
            ans+=(a[i]+charge[id[i]]<k);
    for(int i=id[l]+1;i<id[r];i++)
        ans+=lower_bound(b+lpos[i],b+rpos[i]+1,k-charge[i])-(b+lpos[i]);
    cout<<ans<<endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;len=sqrt(n);
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        if(i%len==1)cnt++,lpos[cnt]=i,rpos[cnt]=i+len-1;
        id[i]=cnt;
    }
    for(int i=1;i<=cnt;i++)mergesort(lpos[i],rpos[i]);
    while(m--)
    {
        char c;cin>>c;
        int l,r,k;cin>>l>>r>>k;
        switch(c)
        {
            case'M':update(l,r,k);break;
            case'A':query(l,r,k);break;
        }
    }
    return 0;
}

|