分块40分求调,剩下的全WA

P2801 教主的魔法

Unknown__ @ 2024-01-28 22:10:03

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define int long long
using namespace std;
int L[20111],R[20111],pos[2011111],n,tot,len,s[2011111],blk[2011111],T,tag[201111];
int query(int l,int r,int x)
{
    int ans = 0,i,j;
    if(pos[l] == pos[r])
    {
        for(i = l;i <= r;i++)if(s[i] + tag[pos[l]] >= x)ans++;
        return ans;
    }
    for(i = l;i <= R[pos[l]];i++)if(s[i] + tag[pos[l]] >= x)ans++;
    for(i = L[pos[r]];i <= r;i++)if(s[i] + tag[pos[r]] >= x)ans++;
    for(i = pos[l] + 1;i < pos[r];i++)
    {
        int ll = L[i],rr = R[i] + 1;
        while(ll < rr)
        {
        //  cout<<ll<<' '<<rr<<endl;
            int mid = ll + rr >> 1;
            if(blk[mid] + tag[i] >= x)rr = mid;
            else ll = mid + 1;
        }
        ans += R[i] - ll + 1;
    }
    return ans;
}
void modify(int l,int r,int x)
{
    int i,j;
    if(pos[l] == pos[r])
    {
        for(i = l;i <= R[pos[l]];i++)
            s[i] += x;
        for(i = L[pos[l]];i <= R[pos[l]];i++)
            blk[i] = s[i];
        sort(blk + L[pos[l]],blk + R[pos[l]]);
        return;
    }
    for(i = l;i <= R[pos[l]];i++)
        s[i] += x;
    for(i = L[pos[l]];i <= R[pos[l]];i++)
        blk[i] = s[i];
    sort(blk + L[pos[l]],blk + R[pos[l]]);
    for(i = L[pos[r]];i <= r;i++)
        s[i] += x;
    for(i = L[pos[r]];i <= R[pos[r]];i++)
        blk[i] = s[i];
    sort(blk + L[pos[r]],blk + R[pos[r]]);
    for(i = pos[l] + 1;i < pos[r];i++)
        tag[i] += x;
}
signed main()
{
    cin>>n>>T;
    int i,j;
    len = sqrt(n);
    tot = len;
    if(n % len)tot++;
    for(i = 1;i <= n;i++)cin>>s[i],blk[i] = s[i];
    for(i = 0;i <= 20001;i++)L[i] = 1e9;
    for(i = 1;i <= n;i++)
    {
        pos[i] = (i - 1) / len + 1;
        L[pos[i]] = min(L[pos[i]],i);
        R[pos[i]] = max(R[pos[i]],i);
    }
    for(i = 1;i <= tot;i++)
        sort(blk + L[pos[i]],blk + R[pos[i]]);
    while(T--)
    {
        char op;cin>>op;
        if(op == 'A')
        {
            int l,r,x;cin>>l>>r>>x;
            cout<<query(l,r,x)<<endl;
        }
        else
        {
            int l,r,x;cin>>l>>r>>x;
            modify(l,r,x);
        }
    }
}

by _Paradox_ @ 2024-01-29 16:32:29

重排的时候肯定会挂,排序是左闭右开,所以右端点得加一


by _Paradox_ @ 2024-01-29 16:33:01

但是改了这个错的又不一样了(

@NG_Jack


by _Paradox_ @ 2024-01-29 16:52:16

找到了,你blk数组初始化排序的时候应该是

for(i = 1;i <= tot;i++)
    sort(blk + L[i],blk + R[i] + 1);

而不是

for(i = 1;i <= tot;i++)
    sort(blk + L[pos[i]],blk + R[pos[i]]);

改了这个还有排序右端点加上一就A了


by Unknown__ @ 2024-01-29 22:38:07

@Paradox %%%%%%orz


by Antiluna @ 2024-03-10 08:10:43

@Paradox dalao 能说一下为什么是左闭右开吗 qwq


by _Paradox_ @ 2024-03-10 18:18:35

@Antiluna 因为 sort 函数就是左闭右开的啊,你 sort(a+l,a+r) 实际上是排的 a_l \sim a_{r-1}


by Antiluna @ 2024-03-11 12:22:58

@Paradox 谢谢


|