题面:https://ac.nowcoder.com/acm/contest/5157/C

 

 

题解

线段树裸题

由于一个细节调了我50min

void insert(int i,int l,int r,LL f,LL d)
{
	if(a[i].l>r||a[i].r<l)return;
	pushdown(i);
	if(l<=a[i].l&&a[i].r<=r){cal(i,(f+d*(a[i].l-l))%mod,d);return;}//!!!!!!!!
	insert(lc,l,r,f,d);insert(rc,l,r,f,d);
	a[i].x=(a[lc].x+a[rc].x)%mod;
}

下传标记的时候分离了等差数列

却忘了在insert的时候分离等差数列

不注重细节!!惨痛教训!!!

 

其他问题

一开始写线段树的时候维护了24个标记,然后T了

后来想到一些数论的东西,发现只需要mod 3*5*7*11*13*17*19*23就可以了

query的时候再来mod一下

证明挺显然的

 

这本应该是一个线段树基础题的

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gi()
{
	char c;int num=0,flg=1;
	while((c=getchar())<'0'||c>'9')if(c=='-')flg=-1;
	while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
	return num*flg;
}
#define N 200005
#define LL long long
const int mod=111546435;
#define lc i<<1
#define rc i<<1|1
int val[N];
struct node{
	int l,r;
	LL x,f,d,len;
}a[N<<2];
inline void cal(int i,LL f,LL d)
{
	(a[i].f+=f)%=mod;(a[i].d+=d)%=mod;
	a[i].x=(a[i].x+1ll*f*a[i].len+(1ll*(a[i].len)*(a[i].len-1)/2)%mod*d)%mod;
}
inline void pushdown(int i)
{
	if(a[i].f&&a[i].l<a[i].r){
		LL f=a[i].f,d=a[i].d;
		cal(lc,f,d);
		cal(rc,(1ll*f+1ll*a[lc].len*d)%mod,d);
		a[i].f=a[i].d=0;
	}
}
void build(int i,int l,int r)
{
	a[i].l=l;a[i].r=r;a[i].len=r-l+1;
	if(l==r){
		a[i].x=val[l]%mod;
		return;
	}
	int mid=(l+r)>>1;
	build(lc,l,mid);build(rc,mid+1,r);
	a[i].x=(a[lc].x+a[rc].x)%mod;
}
void insert(int i,int l,int r,LL f,LL d)
{
	if(a[i].l>r||a[i].r<l)return;
	pushdown(i);
	if(l<=a[i].l&&a[i].r<=r){cal(i,(f+d*(a[i].l-l))%mod,d);return;}//
	insert(lc,l,r,f,d);insert(rc,l,r,f,d);
	a[i].x=(a[lc].x+a[rc].x)%mod;
}
LL query(int i,int l,int r,int mo)
{
	if(a[i].l>r||a[i].r<l)return 0ll;
	pushdown(i);
	if(l<=a[i].l&&a[i].r<=r)return a[i].x;
	return (query(lc,l,r,mo)+query(rc,l,r,mo))%mo;
}
int main()
{
	int n,Q,i,op,l,r,mo,f,d;
	n=gi();
	for(i=1;i<=n;i++)val[i]=gi();
	build(1,1,n);
	Q=gi();
	for(i=1;i<=Q;i++){
		op=gi();l=gi();r=gi();
		if(op==1){
			f=gi();d=gi();
			insert(1,l,r,f,d);
		}
		else{
			mo=gi();
			printf("%lld\n",query(1,l,r,mo));
		}
	}
}