分块+二分样例过不了求条玄关

P2801 教主的魔法

miffy_123 @ 2024-11-26 17:42:03

#include <bits/stdc++.h>
#define int long long
#define rep(i,l,r) for(register int i(l);i^r+1;i=-(~i))
#define per(i,r,l) for(register int i(r);i^l-1;--i)
using namespace std;
inline char getch(){
    static char buf[1 << 20], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? EOF : *p1 ++;
}
inline bool cmp(register signed x, register signed y){
    return y-x>>31;
}
inline bool cmp(register long long x,register long long y){
    return y-x>>63;
}
inline int read(){
    register int x (0),f(1);
    register char c (getchar());
    while(cmp(48,c) | cmp(c,57)) f=(c=='-'?-f:f),c = getchar();
    while((cmp(48,c)^1) & (cmp(c,57)^1)) {x = (x<<1) + (x<<3) + (c^48),c = getchar();}
    return x*f;
}
inline void write(int i){
    if(i<0)putchar('-'),i=-i;
    if(i > 9)write(i / 10) ;
    putchar((i-i/10*10) | 0x30) ;
}
const int mx=1e6+5,D=1005;
struct blck{
    int l,r,tag;
    vector<int>v;
}b[D];
int n=read(),m=read(),a[mx],id[mx],block=sqrt(n),tot;
inline void tag(int k){
    if(b[k].tag){
        vector<int>t;
        rep(i,b[k].l,b[k].r){
            a[i]+=b[k].tag;
            t.push_back(a[i]);
        }
        sort(t.begin(),t.end());
        swap(t,b[k].v);
        b[k].tag=0;
    }
}
inline void chnge(int l,int r,int val){
    tag(id[l]);
    rep(i,l,r)a[i]+=val;
    int k=id[l];
    vector<int>t;
    rep(i,b[k].l,b[k].r){
        t.push_back(a[i]);
    }
    sort(t.begin(),t.end());
    swap(b[k].v,t); 
}
void update(int l,int r,int val){
    if(id[l]==id[r]){
        chnge(l,r,val);
    }
    else{
        chnge(l,b[id[l]].r,val);
        chnge(b[id[r]].l,r,val);
        rep(i,id[l]+1,id[r]-1){
            b[i].tag+=val;
        }
    }
}
inline int gv(int l,int r,int val){
    tag(id[l]);
    int ret=0;
    rep(i,l,r){
        if(a[i]>val){
            ++ret;
        }
    }
    return ret;
}
int lb(int k,int val){
    val-=b[k].tag;
    int l=0,r=b[k].v.size()-1;
    while(l<r){
        int mid=l+r>>1;
        if(b[k].v[mid]>=val){
            r=mid;
        }
        else{
            l=mid+1; 
        }
    }
    return b[k].v.size()-1-l;
}
int ask(int l,int r,int val){
    if(id[l]==id[r]){
        return gv(l,r,val);
    }
    int ret=gv(l,b[id[l]].r,val)+gv(b[id[r]].l,r,val);
    rep(i,id[l]+1,id[r]-1){
        ret+=lb(i,val);
    }
}
signed main(){
    rep(i,1,n){
        a[i]=read();
        if(i%block==1)++tot,b[tot].l=i;
        b[tot].r=i;
        b[tot].v.push_back(a[i]);
    }
    rep(i,1,tot){
        sort(b[i].v.begin(),b[i].v.end());
    }
    rep(i,1,m){
        char c;
        int l,r,val;
        cin>>c>>l>>r>>val;
        if(c=='A'){
            cout<<ask(l,r,val)<<endl;
        }
        else{
            update(l,r,val);
        }
    }
    return 0;
}

by miffy_123 @ 2024-11-28 16:17:53

@quanyidong


by YBB_2110 @ 2024-12-07 13:25:48

第73行的 if(a[i]>val) 改为 if(a[i]>=val) 之后90分,T两个点,建议自己卡常


by miffy_123 @ 2024-12-11 16:14:24

谢谢,已关


|