萌新刚学OI,求调分块,悬赏2关注
查看原帖
萌新刚学OI,求调分块,悬赏2关注
501923
duchengjun楼主2022/8/25 00:52

TLE 70 on 2 9 10

快读有点长,可跳过

#include<bits/stdc++.h>
#define ri register int
#define ll long long
#define ull unsigned long long
using namespace std;
#define getchar() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
namespace get_out
{
    char B[1<<20],*S=B,*T=B;
    char op;
    inline void read_(int &x)
    {
        x=0;
        int fi(1);
        op=getchar();
        while((op<'0'||op>'9')&&op!='-') op=getchar();
        if(op=='-') op=getchar(),fi=-1;
        while(op>='0'&&op<='9') x=(x<<1)+(x<<3)+(op^48),op=getchar();
        x*=fi;
        return;
    }
    inline void read_(long long &x)
    {
        x=0;
        int fi(1);
        op=getchar();
        while((op<'0'||op>'9')&&op!='-') op=getchar();
        if(op=='-') op=getchar(),fi=-1;
        while(op>='0'&&op<='9') x=(x<<1)+(x<<3)+(op^48),op=getchar();
        x*=fi;
        return;
    }
    inline void read_(double &x)
    {
        x=0.0;
        float fi(1.0),sm(0.0);
        op=getchar();
        while((op<'0'||op>'9')&&op!='-') op=getchar();
        if(op=='-') op=getchar(),fi=-1.0;
        while(op>='0'&&op<='9') x=(x*10.0)+(op^48),op=getchar();
        if(op=='.') op=getchar();
        int rtim=0;
        while(op>='0'&&op<='9') sm=(sm*10.0)+(op^48),++rtim,op=getchar();
        while(rtim--) sm/=10.0;
        x+=sm,x*=fi;
        return;
    }
    inline void read_(string &s)
    {
        char c(getchar());
        s="";
        while(!isgraph(c)&&c!=EOF) c=getchar();
        for(;isgraph(c);c=getchar()) s+=c;
    }
    inline void read_(char &c)
    {
        for(c=op;c==' '||c=='\n'||c=='\r'||c=='\t';c=getchar());
        op=c;
    }

    template<typename Head,typename ...Tail>
    inline void read_(Head& h,Tail&... t)
    {read_(h),read_(t...);}

    inline void write_(){}
    inline void postive_write(unsigned x)
    {
        if(x>9) postive_write(x/10);
        putchar(x%10|'0');
    }
    inline void postive_write(unsigned long long x)
    {
        if(x>9) postive_write(x/10);
        putchar(x%10|'0');
    }
    inline void postive_write(int x)
    {
        if(x>9) postive_write(x/10);
        putchar(x%10|'0');
    }
    inline void postive_write(long long x)
    {
        if(x>9) postive_write(x/10);
        putchar(x%10|'0');
    }
    inline void postive_write(short x)
    {
        if(x>9) postive_write(x/10);
        putchar(x%10|'0');
    }
    inline void write_(const char* ss) {while(*ss) putchar(*ss++);}
    inline void write_(char c) {putchar(c);}
    inline void write_(string s) {for(unsigned i=0;i<s.size();++i) putchar(s[i]);}
    inline void write_(short x)
    {
        if(x<0) putchar('-'),postive_write(-x);
        else postive_write(x);
    }
    inline void write_(int x)
    {
        if(x<0) x=-x,putchar('-');
        postive_write(x);
    }
    inline void write_(long long x)
    {
        if(x<0) x=-x,putchar('-');
        postive_write(x);
    }
    inline void write_(unsigned x) {postive_write(x);}
    inline void write_(ull x) {postive_write(x);}

    template<typename Head,typename ...Tail>
    inline void write_(Head h,Tail ...t) {write_(h),write_(t...);}
}
using get_out::read_;
using get_out::write_;
const int N=1e5+10;
struct block{
	ll n,m,MOD,Block;
	ll a[N];
	ll L[N],R[N],pos[N],sum[N];
	ll add[N],mul[N];
	void build(){
		Block=sqrt(n*1.0);
		int num=n/Block;
		if(n%Block!=0)num++;
		for(int i=1;i<=num;i++)
			L[i]=(i-1)*Block+1,R[i]=i*Block,mul[i]=1;
		R[num]=n;
		for(int i=1;i<=num;i++)
			for(int j=L[i];j<=R[i];j++)
				pos[j]=i,sum[i]=(sum[i]+a[j])%MOD;
	}
	void update_add_small(ll k,ll l,ll r,ll d){
		for(int i=L[k];i<=R[k];i++)a[i]=(a[i]*mul[k]%MOD+add[k]+MOD)%MOD;
		sum[k]=(sum[k]+(r-l+1)*d%MOD)%MOD;
		for(int i=l;i<=r;i++)a[i]=(a[i]+d+MOD)%MOD;
		add[k]=0,mul[k]=1;
	}
	void update_add(ll l,ll r,ll d){
		int p=pos[l],q=pos[r];
		if(p==q){update_add_small(p,l,r,d);}
		else{
			for(int i=p+1;i<=q-1;i++)add[i]=(add[i]+d+MOD)%MOD,sum[i]=(sum[i]+Block*d%MOD)%MOD;
			update_add_small(p,l,R[p],d),update_add_small(q,L[q],r,d);
		}
	}
	void update_mul_small(ll k,ll l,ll r,ll d){
		for(int i=L[k];i<=R[k];i++)a[i]=(a[i]*mul[k]%MOD+add[k]+MOD)%MOD;
		for(int i=l;i<=r;i++)sum[k]+=(d-1)*a[i]%MOD,a[i]=(a[i]*d+MOD)%MOD;
		add[k]=0,mul[k]=1;
	}
	void update_mul(ll l,ll r,ll d){
		int p=pos[l],q=pos[r];
		if(p==q){update_mul_small(p,l,r,d);}
		else{
			for(int i=p+1;i<=q-1;i++)mul[i]=(mul[i]*d+MOD)%MOD,add[i]=(add[i]*d+MOD)%MOD,sum[i]=(sum[i]*d+MOD)%MOD;
			update_mul_small(p,l,R[p],d),update_mul_small(q,L[q],r,d);
		}
	}
	ll query_small(ll k,ll l,ll r){
		ll ans=0;
		for(int i=l;i<=r;i++)ans=(ans+a[i]*mul[k]%MOD+add[k])%MOD;
		return ans;
	}
	ll query(ll l,ll r){
		ll p=pos[l],q=pos[r];
		ll ans=0;
		if(p==q){ans=query_small(p,l,r);}
		else{
			for(int i=p+1;i<=q-1;i++)ans=(ans+sum[i])%MOD;
			ans=(ans+query_small(p,l,R[p])+query_small(q,L[q],r))%MOD;
		}
		return ans;
	}
	void CIN(){
		read_(n,m,MOD);
		for(int i=1;i<=n;i++){read_(a[i]);a[i]%=MOD;};
	}
	void COUT(){
		while(m--){
			int opt,l,r,d;
			read_(opt,l,r);
			if(opt==1){
				read_(d);
				update_mul(l,r,d);
			}else if(opt==2){
				read_(d);
				update_add(l,r,d);
			}else
				write_(query(l,r),"\n");
		}
	}
}a;
signed main(void){
	std::ios::sync_with_stdio(false);
	a.CIN();
	a.build();
	a.COUT();
	cout<<endl;
	return 0;
}

2022/8/25 00:52
加载中...