BZOJ 3343 教主的魔法 分块

mdzz....我的-Wall怕不是被吃了。。。快读里面==写成了=。。。。艹。。。调了一中午、、、QWQ我的时间啊。。。


分块:块内排序加tag(就是偏移量),来二分比所求大的位置;散块暴力修改。。。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define R register int
using namespace std;
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
int n,m,q,T;
int a[1000010],s[1000010],pos[1000010],tg[1000010];
inline void build(int p) {
    R l=(p-1)*T+1,r=min(p*T,n);
    for(R i=l;i<=r;++i) s[i]=a[i];
    sort(s+l,s+r+1);
}
inline int calc(int p,int d) {
    R l=(p-1)*T+1,r=min(p*T,n);
    R tmp=lower_bound(s+l,s+r+1,d)-s-1;
    return r-tmp;
}
inline void update(int l,int r,int d) {
    if(pos[l]==pos[r]) for(R i=l;i<=r;++i) a[i]+=d;
    else {
        for(R i=l;i<=pos[l]*T;++i) a[i]+=d;
        for(R i=(pos[r]-1)*T+1;i<=r;++i) a[i]+=d;
    } pos[l]==pos[r]?build(pos[l]):build(pos[l]),build(pos[r]);
    for(R i=pos[l]+1;i<pos[r];++i) tg[i]+=d;
}
inline int query(int l,int r,int d) {
    R ret=0; if(pos[l]==pos[r]) {for(R i=l;i<=r;++i) if(a[i]+tg[pos[i]]>=d) ++ret;}
    else { 
        for(R i=l;i<=pos[l]*T;++i) if(a[i]+tg[pos[i]]>=d) ++ret;
        for(R i=(pos[r]-1)*T+1;i<=r;++i) if(a[i]+tg[pos[i]]>=d)    ++ret; 
    } for(R i=pos[l]+1;i<pos[r];++i) ret+=calc(i,d-tg[i]);
    return ret;
}
signed main() {
    n=g(),q=g(); T=1000; 
    for(R i=1;i<=n;++i) s[i]=a[i]=g(); for(R i=1;i<=n;++i) pos[i]=(i-1)/T+1;
    if(n%T) m=n/T+1; else m=n/T; 
    for(R i=1;i<=m;++i) build(i);
    for(R i=1;i<=q;++i) { register char ch;
        while(!isalpha(ch=getchar())); R l=g(),r=g(),d=g(); 
        if(ch=='M') update(l,r,d);
        else printf("%d\n",query(l,r,d)); 
    }
}

f我再也不能写错快读了。。。2019.04.23

 

posted @ 2019-04-23 14:17  LuitaryiJack  阅读(69)  评论(0编辑  收藏