TLE on #8 求助

P2801 教主的魔法

qwq___qaq @ 2022-02-27 15:24:19

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5,maxk=1e3+5;
int n,q,len,t,L[maxk],R[maxk],del[maxn],a[maxn],b[maxn],tag[maxk];
inline int f(int x,int k){
    int qwq=R[x]-L[x]+1;
    int l=0,r=qwq;
    while(l<r){
        int mid=l+r+1>>1;
        if(b[L[x]+mid-1]>=k)
            l=mid;
        else
            r=mid-1;
    }
    return r;
}
inline int read(){
    char ch=getchar();
    int res=0;
    while(ch<'0'||ch>'9')
        ch=getchar();
    while(ch>='0'&&ch<='9'){
        res=(res<<1)+(res<<3)+(ch^'0');
        ch=getchar();
    }
    return res;
}
int main(){
    n=read(),q=read();
    len=sqrt(n);
    t=(n+len-1)/len;
    for(int i=1;i<=n;++i)
        b[i]=a[i]=read();
    for(int i=1;i<=t;++i){
        L[i]=(i-1)*len+1;
        R[i]=min(n,i*len);
        sort(b+L[i],b+R[i]+1);
    }
    for(int i=1;i<=q;++i){
        char c=getchar();
        while(c!='M'&&c!='A')
            c=getchar();
        int l=read(),r=read(),k=read();
        int x=del[l],y=del[r];
        if(c=='M'){
            if(x==y){
                for(int j=l;j<=r;++j)
                    a[j]+=k;
                for(int j=L[x];j<=R[x];++j)
                    b[j]=a[j];
                sort(b+L[x],b+R[x]+1);
            } else{
                for(int j=l;j<=R[x];++j)
                    a[j]+=k;
                for(int j=L[x];j<=R[x];++j)
                    b[j]=a[j];
                sort(b+L[x],b+R[x]+1);
                for(int j=L[y];j<=r;++j)
                    a[j]+=k;
                for(int j=L[y];j<=R[y];++j)
                    b[j]=a[j];
                sort(b+L[x],b+R[x]+1);
                for(int j=x+1;j<y;++j)
                    tag[j]+=k;
            }
        } else{
            int ans=0;
            if(x==y){
                for(int j=l;j<=r;++j)
                    ans+=(a[j]+tag[x]>=k);
            } else{
                for(int j=l;j<=R[x];++j)
                    ans+=(a[j]+tag[x]>=k);
                for(int j=L[y];j<=r;++j)
                    ans+=(a[j]+tag[y]>=k);
                for(int j=x+1;j<y;++j)
                    ans+=f(j,k-tag[j]);
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}

by Engulf @ 2022-02-27 15:55:29

对于中间完整的块,用一个辅助数组排序,然后二分求解。


by Engulf @ 2022-02-27 15:56:36

例如

for(int i=x+1;i<=y-1;i++){
    ans+=lower_bound(d+L[i],d+R[i]+1,k-add[i])-d-L[i];
}

by qwq___qaq @ 2022-02-27 22:43:52

@TMJYH09 我手写二分应该没问题啊


|