刚学OI $10^{-998244353}$ ms,线段树30分求助
查看原帖
刚学OI $10^{-998244353}$ ms,线段树30分求助
307453
云浅知处はなび楼主2020/7/8 12:18

调一天了....../kk/kk

记录

这里是代码:

#pragma GCC optimize(3)
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")

#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<cstdlib>

#define MAXN 100005
#define lson(o) (o<<1)
#define rson(o) (o<<1|1)

//#define gc getchar()
//#define id(ch) (ch>='0'&&ch<='9')

using namespace std;

int a[MAXN],n,m,cf[MAXN];

/*inline int read(){
	int w=0,f=1;char ch=gc;
	while(!(id(ch)))if(ch=='-')f=-1,ch=gc;
	while(id(ch))w=(w<<1)+(w<<3)+(ch-'0'),ch=gc;
	return w*f;
}*/

struct SMT{

	int sumv[MAXN<<2];
	int plz[MAXN<<2];

	inline void pushup(int o){
		sumv[o]=sumv[lson(o)]+sumv[rson(o)];
	}

	inline void build(int l,int r,int o){
		plz[o]=0;
		if(l==r){
			sumv[o]=cf[l];
			return ;
		}
		int mid=(l+r)>>1;
		build(l,mid,lson(o));
		build(mid+1,r,rson(o));
		pushup(o);
	}

	inline void pushdown(int ql,int qr,int o){
		if(plz[o]){
			int mid=(ql+qr)>>1;
			sumv[lson(o)]+=(mid-ql+1)*plz[o];
			sumv[rson(o)]+=(qr-mid)*plz[o];
			plz[lson(o)]+=plz[o];
			plz[rson(o)]+=plz[o];
			plz[o]=0;
		}
	}

	inline void change(int l,int r,int k,int ql,int qr,int o){
		if(l<=ql&&qr<=r){
			sumv[o]+=(qr-ql+1)*k;
			plz[o]+=k;
			return ;
		}
		pushdown(ql,qr,o);
		int mid=(ql+qr)>>1;
		if(l<=mid)change(l,r,k,ql,mid,lson(o));
		if(r>mid)change(l,r,k,mid+1,qr,rson(o));
		pushup(o);
	}

	inline int QrySum(int l,int r,int ql,int qr,int o){
		if(l<=ql&&qr<=r){
			return sumv[o];
		}
		pushdown(ql,qr,o);
		int mid=(ql+qr)>>1;
		int ans=0;
		if(l<=mid)ans+=QrySum(l,r,ql,mid,lson(o));
		if(r>mid)ans+=QrySum(l,r,mid+1,qr,rson(o));
		return ans;
	}

};

SMT tree;

void print(){
	for(int i=1;i<=n;i++){
		printf("%d ",cf[i]);
	}
	puts("");
}

void printt(){
	for(int i=1;i<=(n<<1)+4;i++){
		printf("%d ",tree.plz[i]);
	}
	puts("");
	for(int i=1;i<=(n<<1)+4;i++){
		printf("%d ",tree.sumv[i]);
	}
}

int main(void){

	scanf("%d%d",&n,&m);

	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		cf[i]=a[i]-a[i-1];
	}

	tree.build(1,n,1);

	//print();
	//printt();

	while(m--){
		int opt,l,r,d,k,p;
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d%d%d%d",&l,&r,&k,&d);
			tree.change(l,l,k,1,n,1);
			tree.change(r+1,r+1,(l-r)*d-k,1,n,1);
			tree.change(l+1,r,d,1,n,1);
		}
		else{
			scanf("%d",&p);
			printf("%d\n",a[1]+tree.QrySum(2,p,1,n,1));
		}
		//print();
		//printt();
	}

	return 0;
}
2020/7/8 12:18
加载中...