[BZOJ4373]算术天才⑨与等差数列

[BZOJ4373]算术天才⑨与等差数列

BZOJ
标准的做法似乎是线段树维护原数组的最大最小值,差分数组的gcd以及pre数组的最大值
pre表示上一个与该数值相同的下标(然后这个修改我不太会,好像是用个set搞一搞)
那么蒟蒻用一种更快的方法过掉此题
可以线段树维护最小值以及平方和和立方和(对大质数取模)
我只能说这样非常难卡,非常非常难卡,如果有hack数据欢迎下方评论

[a_1^2+(a_1+d)^2+...+[a_1+(n-1)d]^2=na_1^2+n(n-1)a_1d+frac{n(n-1)(2n-1)}{6}d^2 ]

[a_1^3+(a_1+d)^3+...+[a_1+(n-1)d]^3=na_1^3+frac{3n(n-1)a_1^2d}{2}+frac{n(n-1)(2n-1)a_1d^2}{2}+frac{n^2(n-1)^2}{4}d^3 ]

#define ll long long
#define ls x<<1,l,mid
#define rs x<<1|1,mid+1,r
#include<bits/stdc++.h>
using namespace std;
const int _=3e5+5,p=1e9+7;
int re(){
	int x=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*w;
}
int n,m,yes,Mn,S2,S3,inv2=500000004,inv4=250000002,inv6=166666668;
int mn[_<<2],s2[_<<2],s3[_<<2];
inline int js2(ll s,ll x,ll d){
	return ((x*s%p*s%p+x*(x-1)%p*s%p*d%p)%p+
			(x*(x-1)%p*(2*x-1)%p*inv6%p*d%p*d%p)%p)%p;
}
inline int js3(ll s,ll x,ll d){
	return ((x*s%p*s%p*s%p+x*(x-1)*inv2%p*3%p*s%p*s%p*d%p)%p+
			(x*(x-1)%p*inv2%p*(2*x-1)%p*s%p*d%p*d%p+
			 x*x%p*(x-1)%p*(x-1)%p*inv4%p*d%p*d%p*d%p)%p)%p;
}
inline void in(int x,int v){
	mn[x]=v;s2[x]=1ll*v*v%p;s3[x]=1ll*v*v%p*v%p;
}
inline void pu(int x){
	int L=x<<1,R=x<<1|1;
	mn[x]=min(mn[L],mn[R]);
	s2[x]=(s2[L]+s2[R])%p;s3[x]=(s3[L]+s3[R])%p;
}
void bu(int x,int l,int r){
	if(l==r){in(x,re());return;}
	int mid=(l+r)>>1;bu(ls);bu(rs);pu(x);
}
void upd(int x,int l,int r,int k,int v){
	if(l==r){in(x,v);return;}
	int mid=(l+r)>>1;if(k<=mid)upd(ls,k,v);
	else upd(rs,k,v);pu(x);
}
void q(int x,int l,int r,int ql,int qr){
	if(ql<=l&&r<=qr){
		Mn=min(Mn,mn[x]);S2=(S2+s2[x])%p;
		S3=(S3+s3[x])%p;return;
	}
	int mid=(l+r)>>1;if(ql<=mid)q(ls,ql,qr);
	if(qr>mid)q(rs,ql,qr);
}
int main(){
	n=re(),m=re();bu(1,1,n);
	int op,x,y,k;
	while(m--){
		op=re(),x=re()^yes,y=re()^yes;
		if(op==1)upd(1,1,n,x,y);
		else{
			Mn=1e9+1;S2=S3=0;
			k=re()^yes;q(1,1,n,x,y);
			ll sum2=js2(Mn,y-x+1,k);
			ll sum3=js3(Mn,y-x+1,k);
			if((sum2==S2&&sum3==S3)||y-x==0){yes++;puts("Yes");}
			else puts("No");
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/sdzwyq/p/9889132.html