cunzai_zsy0531

关注我

P2801 教主的魔法 题解

分块之后,一定要注意你操作之后的数组并不是修改的区间!

点击查看代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#include<map>
#include<bitset>
#include<set>
#include<unordered_map>
#include<random>
#include<chrono>
#include<deque>
#include<cassert>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<vector>
#define fi first
#define se second
#define pb push_back
#define mp std::make_pair
#define ulf Useful_little_function
#define abs ccf
#define INF (0x3f3f3f3f)
#define INT_INF (2147483647)
#define LLINF (0x3f3f3f3f3f3f3f3fll)
#define LL_INF (9223372036854775807)
#define memset __builtin_memset
#define popcount __builtin_popcount
std::mt19937 rnd(std::chrono::system_clock::now().time_since_epoch().count());
typedef long long ll;
typedef std::pair<int,int> pii;
typedef unsigned int uint;
typedef unsigned long long ull;
inline void file(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
namespace IO{
    #define BUF_SIZE (1<<16)
    #define OUT_SIZE (1<<16)
    bool IOerror=0;
    inline char nc(){static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;if(p1==pend){p1=buf;pend=buf+fread(buf,1,BUF_SIZE,stdin);if(pend==p1)return IOerror=1,-1;}return *p1++;}
    inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
    inline void read(int &x){bool sign=0;char ch=nc();x=0;for(;blank(ch);ch=nc());if(IOerror)return;if(ch=='-')sign=1,ch=nc();for(;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';if(sign)x=-x;}
    inline void read(ll &x){bool sign=0;char ch=nc();x=0;for(;blank(ch);ch=nc());if(IOerror)return;if(ch=='-')sign=1,ch=nc();for(;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';if(sign)x=-x;}
    inline void read(double &x){bool sign=0;char ch=nc();x=0;for(;blank(ch);ch=nc());if(IOerror)return;if(ch=='-')sign=1,ch=nc();for(;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';if(ch=='.'){double tmp=1;ch=nc();for(;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');}if(sign)x=-x;}
    inline void read(char *s){char ch=nc();for(;blank(ch);ch=nc());if(IOerror)return;for(;!blank(ch)&&!IOerror;ch=nc())*s++=ch;*s=0;}
    inline void read(char &c){for(c=nc();blank(c);c=nc());if(IOerror){c=-1;return;}}
    struct Ostream_fwrite{
        char *buf,*p1,*pend;
        Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
        inline void out(char ch){if(p1==pend){fwrite(buf,1,BUF_SIZE,stdout);p1=buf;}*p1++=ch;}
        inline void print(int x){static char s[15],*s1;s1=s;if(!x)*s1++='0';if(x<0)out('-'),x=-x;while(x)*s1++=x%10+'0',x/=10;while(s1--!=s)out(*s1);}
        inline void println(int x){print(x);out('\n');}
        inline void print(ll x){static char s[25],*s1;s1=s;if(!x)*s1++='0';if(x<0)out('-'),x=-x;while(x)*s1++=x%10+'0',x/=10;while(s1--!=s)out(*s1);}
        inline void println(ll x){print(x);out('\n');}
        inline void print(double x,int y){//y<18
			static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
            if(x<-1e-12)out('-'),x=-x;x*=mul[y];ll x1=(ll)floor(x);if(x-floor(x)>=0.5)++x1;ll x2=x1/mul[y],x3=x1-x2*mul[y];print(x2);if(y>0){out('.');for(size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i);print(x3);}
        }
        inline void println(double x,int y){print(x,y);out('\n');}
        inline void print(char *s){while(*s)out(*s++);}
        inline void println(char *s){while(*s)out(*s++);out('\n');}
        inline void flush(){if(p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
        ~Ostream_fwrite(){flush();}
    }Ostream;
    inline void print(int x){Ostream.print(x);}
    inline void println(int x){Ostream.println(x);}
    inline void print(char x){Ostream.out(x);}
    inline void println(char x){Ostream.out(x);Ostream.out('\n');}
    inline void print(ll x){Ostream.print(x);}
    inline void println(ll x){Ostream.println(x);}
    inline void print(double x,int y){Ostream.print(x,y);}
    inline void println(double x,int y){Ostream.println(x,y);}
    inline void print(char *s){Ostream.print(s);}
    inline void println(char *s){Ostream.println(s);}
    inline void println(){Ostream.out('\n');}
    inline void flush(){Ostream.flush();}
    #undef OUT_SIZE
    #undef BUF_SIZE
}using namespace IO;
namespace Little_function{
	inline int abs(int x){return x<0?-x:x;}
	inline ll abs(ll x){return x<0?-x:x;}
	inline double abs(double x){return x<0?-x:x;}
	inline int max(const int &a,const int &b){return a>b?a:b;}
	inline ll max(const ll &a,const ll &b){return a>b?a:b;}
	inline double max(const double &a,const double &b){return a>b?a:b;}
	inline int min(const int &a,const int &b){return a<b?a:b;}
	inline ll min(const ll &a,const ll &b){return a<b?a:b;}
	inline double min(const double &a,const double &b){return a<b?a:b;}
	inline void chkmax(int &a,const int &b){if(b>a)a=b;}
	inline void chkmax(ll &a,const ll &b){if(b>a)a=b;}
	inline void chkmax(double &a,const double &b){if(b>a)a=b;}
	inline void chkmin(int &a,const int &b){if(b<a)a=b;}
	inline void chkmin(ll &a,const ll &b){if(b<a)a=b;}
	inline void chkmin(double &a,const double &b){if(b<a)a=b;}
	inline void swap(int &x,int &y){x^=y^=x^=y;}
	inline void swap(ll &x,ll &y){x^=y^=x^=y;}
	inline void swap(double &x,double &y){double t=x;x=y,y=t;}
	inline int madd(const int &a,const int &b,const int &p){return (a+b)%p;}
	inline int mdel(const int &a,const int &b,const int &p){return (a-b<0?a-b+p:a-b);}
	int gcd(int a,int b){return !b?a:gcd(b,a%b);}
	ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}
}using namespace Little_function;
namespace modint{
	#define N 200005
	const int mod=1e9+7;
	int ni[N],mul[N],invmul[N];
	inline int md(const int &x){return x>=mod?x-mod:x;}
	inline int madd(const int &x,const int &y){return x+y<mod?x+y:x+y-mod;}
	inline int mdel(const int &x,const int &y){return x-y<0?x-y+mod:x-y;}
	inline void modadd(int &x,const int &y){x=(x+y<mod?x+y:x+y-mod);}
	inline void moddel(int &x,const int &y){x=(x-y<0?x-y+mod:x-y);}
	inline int qpow(int a,int k){int s=1;for(;k;k>>=1,a=(ll)a*a%mod)if(k&1)s=(ll)s*a%mod;return s;}
	inline void _init(int n){
		ni[1]=1;
		for(int i=2;i<=n;++i) ni[i]=mod-(ll)ni[mod%i]*(mod/i)%mod;
		mul[0]=invmul[0]=1;
		for(int i=1;i<=n;++i) mul[i]=(ll)mul[i-1]*i%mod;
		invmul[n]=qpow(mul[n],mod-2);
		for(int i=n-1;i;--i) invmul[i]=(ll)invmul[i+1]*(i+1)%mod;
	}
	inline int C(int n,int m){if(m>n)return 0;return (ll)mul[n]*invmul[m]%mod*invmul[n-m]%mod;}
	#undef N
}
const int N=1e6+13,SqN=3000+13;
struct Block{int a[SqN],tag;}s[SqN];
int n,q,m,b[N],from[N],L[SqN],R[SqN];
int main(){
#ifdef LOCAL
	freopen("ex_p2.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	read(n),read(q);int tt=1000;
	for(int i=1;i<=n;++i) read(b[i]);
	L[m=1]=1;
	for(int i=1;i<=n;++i){
		from[i]=m;
		if(i%tt==0){
			R[m]=i;
			if(i<n) L[++m]=i+1;
		}
	}
	if(!R[m]) R[m]=n;
	for(int i=1;i<=m;++i){
		int c=0;
		for(int j=L[i];j<=R[i];++j) s[i].a[++c]=b[j];
		std::sort(s[i].a+1,s[i].a+R[i]-L[i]+2);
	}
	while(q--){
		char c;int l,r,x;read(c),read(l),read(r),read(x);
		if(c=='M'){
			if(from[l]==from[r]){
				int p=from[l];
				for(int i=L[p];i<=R[p];++i) b[i]+=s[p].tag;s[p].tag=0;
				for(int i=l;i<=r;++i) b[i]+=x;
				for(int i=L[p];i<=R[p];++i) s[p].a[i-L[p]+1]=b[i];
				std::sort(s[p].a+1,s[p].a+R[p]-L[p]+2);
			}
			else{
				int p=from[l];
				for(int i=L[p];i<=R[p];++i) b[i]+=s[p].tag;s[p].tag=0;
				for(int i=l;i<=R[p];++i) b[i]+=x;
				for(int i=L[p];i<=R[p];++i) s[p].a[i-L[p]+1]=b[i];
				std::sort(s[p].a+1,s[p].a+R[p]-L[p]+2);
				p=from[r];
				for(int i=L[p];i<=R[p];++i) b[i]+=s[p].tag;s[p].tag=0;
				for(int i=L[p];i<=r;++i) b[i]+=x;
				for(int i=L[p];i<=R[p];++i) s[p].a[i-L[p]+1]=b[i];
				std::sort(s[p].a+1,s[p].a+R[p]-L[p]+2);
				for(int i=from[l]+1;i<from[r];++i) s[i].tag+=x;
			}
		}
		else{
			if(from[l]==from[r]){
				int p=from[l],ans=0;
				for(int i=l;i<=r;++i) ans+=(b[i]+s[p].tag>=x);
				println(ans);
			}
			else{
				int ans=0,p=from[l];
				for(int i=l;i<=R[p];++i) ans+=(b[i]+s[p].tag>=x);
				p=from[r];
				for(int i=L[p];i<=r;++i) ans+=(b[i]+s[p].tag>=x);
				for(int i=from[l]+1;i<from[r];++i){
					int val=x-s[i].tag;
					if(s[i].a[R[i]-L[i]+1]<val) continue;
					int _l=1,_r=R[i]-L[i]+1;
					while(_l<_r){
						int mid=(_l+_r)>>1;
						if(s[i].a[mid]>=val) _r=mid;
						else _l=mid+1;
					}
					ans+=(R[i]-L[i]+1-_l+1);
				}
				println(ans);
			}
		}
	}
	return 0;
}
posted @ 2022-05-03 13:26  cunzai_zsy0531  阅读(14)  评论(0编辑  收藏  举报