RE 求助
查看原帖
RE 求助
115857
too_later楼主2021/10/2 23:52

万能的谷民啊,时间可以加八倍,卡空间。

#include<bits/stdc++.h>
#define ls tr[p].l
#define rs tr[p].r 
#define I inline
#define RI register int
#define rep(i,a,b) for(RI i=a;i<=b;++i)
#define dow(i,a,b) for(RI i=a;i>=b;--i)
#define edg(i,u,v) for(RI v,i=head[u];v=e[i].to,i;i=e[i].next)
using namespace std;

const int N=5e5+5;

struct tree{
	int l,r,a,b,x,y;
	long long sum;
	tree(){ sum=0; }
} tr[N<<2];

int n,m,op,X,tot,Y,a,b,rt;
I long long solve(long long a,long long b,long long c,long long n){
	if(!a) return (b/c)*(n+1);
	if(a>=c||b>=c) return solve(a%c,b%c,c,n)+(b/c)*(n+1)+n*(n+1)/2*(a/c);
	else return (a*n+b)/c*n-solve(c,c-b-1,a,(a*n+b)/c-1);
}
I void update(int l,int r,int nl,int nr,int &p,int x,int y){
	if(!p) p=++tot;
	if(l==nl&&r==nr)
		return (void)(tr[p].a=x,tr[p].b=y,tr[p].x=l-X+1,tr[p].y=r-X+1,
			tr[p].sum=(long long)(tr[p].y-tr[p].x+1)*(tr[p].y+tr[p].x)/2*x-
				(long long)y*(solve(x,0,y,tr[p].y)-solve(x,0,y,tr[p].x-1)));
	RI mid=nl+nr>>1;
	if(tr[p].a) {
		if(!ls) ls=++tot;if(!rs) rs=++tot;
		tr[ls].a=tr[rs].a=tr[p].a,tr[ls].b=tr[rs].b=tr[p].b;
		tr[ls].x=tr[p].x,tr[rs].x=tr[p].x+mid+1-nl;
		tr[ls].y=tr[rs].x-1,tr[rs].y=tr[p].y;
		tr[ls].sum=(long long)(tr[ls].y-tr[ls].x+1)*(tr[ls].y+tr[ls].x)/2*tr[ls].a
			-(long long)tr[p].b*(solve(tr[ls].a,0,tr[ls].b,tr[ls].y)-solve(tr[ls].a,0,tr[ls].b,tr[ls].x-1));
		tr[rs].sum=(long long)(tr[rs].y-tr[rs].x+1)*(tr[rs].y+tr[rs].x)/2*tr[rs].a
			-(long long)tr[p].b*(solve(tr[rs].a,0,tr[rs].b,tr[rs].y)-solve(tr[rs].a,0,tr[rs].b,tr[rs].x-1));
	}
	if(l>mid) update(l,r,mid+1,nr,tr[p].r,x,y);
	else if(r<=mid) update(l,r,nl,mid,tr[p].l,x,y);
	else update(l,mid,nl,mid,tr[p].l,x,y),update(mid+1,r,mid+1,nr,tr[p].r,x,y);
	tr[p].sum=tr[ls].sum+tr[rs].sum;
	tr[p].a=tr[p].b=tr[p].x=tr[p].y=0;
}
I long long query(int l,int r,int ql,int qr,int p){
	if(!p) return 0;
	if(l==ql&&r==qr) return tr[p].sum;
	RI mid=ql+qr>>1;if(tr[p].a) {
		if(!ls) ls=++tot;if(!rs) rs=++tot;
		tr[ls].a=tr[rs].a=tr[p].a,tr[ls].b=tr[rs].b=tr[p].b;
		tr[ls].x=tr[p].x,tr[rs].x=tr[p].x+mid+1-ql;
		tr[ls].y=tr[rs].x-1,tr[rs].y=tr[p].y;
		tr[ls].sum=(long long)(tr[ls].y-tr[ls].x+1)*(tr[ls].y+tr[ls].x)/2*tr[ls].a
			-(long long)tr[p].b*(solve(tr[ls].a,0,tr[ls].b,tr[ls].y)-solve(tr[ls].a,0,tr[ls].b,tr[ls].x-1));
		tr[rs].sum=(long long)(tr[rs].y-tr[rs].x+1)*(tr[rs].y+tr[rs].x)/2*tr[rs].a
			-(long long)tr[p].b*(solve(tr[rs].a,0,tr[rs].b,tr[rs].y)-solve(tr[rs].a,0,tr[rs].b,tr[rs].x-1));
	}
	if(l>mid) return query(l,r,mid+1,qr,rs);
	else if(r<=mid) return query(l,r,ql,mid,ls);
	else return query(l,mid,ql,mid,ls)+query(mid+1,r,mid+1,qr,rs);
}
signed main(){
//	freopen("2.in","r",stdin);
//	freopen("3.out","w",stdout);
	scanf("%d%d",&n,&m);
	while(m--){
		scanf("%d",&op);
		if(op==1) scanf("%d%d%d%d",&X,&Y,&a,&b),update(X,Y,1,n,rt,a,b);
		else scanf("%d%d",&X,&Y),printf("%lld\n",query(X,Y,1,n,rt));
	}
	return 0;
}
2021/10/2 23:52
加载中...