牛客挑战赛39 牛牛的等差数列

LINK:牛牛的等差数列

每次给一个区间加上一个等差数列 求区间和。

不是李超线段树==.

也不是等比数列 所以等差数列具有区间可加性。

考虑一个标记d(p)表示节点p这个区间的等差数列要逐渐加d(p).

这个可以当做懒标记下传。

注意下传的时候 左边对右边的贡献要乘上整个区间 修改也是。

细节挺多。最后值得一提的是模数 发现模数有很多 答案也是爆longlong的 不可能维护对应那么多模数的答案。

考虑对他们的乘积取模 他们乘积也不算很大 最后再对某个模数单独取模 正确性显然。

等差数列求和时 因为这个东西还是可能爆longlong 所以求出2的逆元 不需要exgcd 因为2和mod互质 且mod的欧拉函数很好求 可以利用欧拉定理 即2的mod的欧拉函数-1次幂就是逆元。

//#include<bitsstdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 2100000000
#define ldb long double
#define pb push_back
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define put(x) printf("%d
",x)
#define putl(x) printf("%lld
",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE ll i=p;i<=n;++i)
#define go(x) for(ll i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE ll i=n;i>=p;--i)
#define pii pair<ll,ll> 
#define mk make_pair
#define RE register
#define P 1000000007
#define F first
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define ull unsigned long long
#define ui unsigned
#define mod 111546435
#define l(x) t[x].l
#define r(x) t[x].r
#define sum(x) t[x].sum
#define tag(x) t[x].tag
#define d(x) t[x].d
#define zz p<<1
#define yy p<<1|1
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
    return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline ll read()
{
    RE ll x=0,f=1;register char ch=getc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    return x*f;
}
const ll MAXN=200010;
ll n,Q,INV2,phi=36495360;
struct wy
{
	ll l,r;
	ll sum;
	ll d,tag;
}t[MAXN<<2];
ll a[MAXN];
inline ll ksm(ll b,ll p)
{
	ll cnt=1;
	while(p)
	{
		if(p&1)cnt=cnt*b%mod;
		b=b*b%mod;p=p>>1;
	}
	return cnt;
}
inline void build(ll p,ll l,ll r)
{
	l(p)=l;r(p)=r;
	if(l==r){sum(p)=a[l]%mod;return;}
	ll mid=(l(p)+r(p))>>1;
	build(zz,l,mid);build(yy,mid+1,r);
	sum(p)=(sum(zz)+sum(yy))%mod;
}
inline void pushdown(ll p)
{
	ll mid=(l(p)+r(p))>>1;
    if(tag(p))
	{
		tag(zz)=(tag(zz)+tag(p))%mod;
		tag(yy)=(tag(yy)+tag(p))%mod;
		sum(yy)=(sum(yy)+(r(p)-mid)*tag(p))%mod;
		sum(zz)=(sum(zz)+(mid-l(p)+1)*tag(p))%mod;
		tag(p)=0;
	}
	if(d(p))
	{
		ll ww=mid-l(p)+1;
		d(zz)=(d(zz)+d(p))%mod;
		sum(zz)=(sum(zz)+(d(p)+d(p)*ww)%mod*ww%mod*INV2)%mod;
		d(yy)=(d(yy)+d(p))%mod;
		ww=r(p)-mid;
		sum(yy)=(sum(yy)+(d(p)+d(p)*ww)%mod*ww%mod*INV2+d(p)*(mid-l(p)+1)%mod*(r(p)-mid)%mod)%mod;
		tag(yy)=(tag(yy)+(mid-l(p)+1)*d(p))%mod;
		d(p)=0;
	}
}
inline void change(ll p,ll l,ll r,ll v)
{
	if(l<=l(p)&&r>=r(p))
	{
		ll ww=r(p)-l(p)+1;
		sum(p)=(sum(p)+ww*v)%mod;
		tag(p)=(tag(p)+v)%mod;
		return;
	}
	ll mid=(l(p)+r(p))>>1;
	if(tag(p)||d(p))pushdown(p);
	if(l<=mid)change(zz,l,r,v);
	if(r>mid)change(yy,l,r,v);
	sum(p)=(sum(zz)+sum(yy))%mod;
}
inline void modify(ll p,ll l,ll r,ll v,ll d)
{
	if(l>r)return;
	if(l<=l(p)&&r>=r(p))
	{
		ll ww=r(p)-l(p)+1;
		sum(p)=(sum(p)+(d+d*ww)%mod*ww%mod*INV2%mod+v*ww%mod)%mod;
		tag(p)=(tag(p)+v)%mod;
		d(p)=(d(p)+d)%mod;
		return;
	}
	if(tag(p)||d(p))pushdown(p);
	ll mid=(l(p)+r(p))>>1;
	if(r<=mid)modify(zz,l,r,v,d);
	else 
	{
		if(l>mid)modify(yy,l,r,v,d);
		else
		{
			modify(zz,l,mid,v,d);
			modify(yy,mid+1,r,(v+(mid-l+1)*d)%mod,d);
		}
	}
	sum(p)=(sum(zz)+sum(yy))%mod;
}
inline ll ask(ll p,ll l,ll r)
{
	if(l<=l(p)&&r>=r(p))return sum(p);
	ll mid=(l(p)+r(p))>>1;
	ll cnt=0;
	if(tag(p)||d(p))pushdown(p);
	if(l<=mid)cnt=(cnt+ask(zz,l,r))%mod;
	if(r>mid)cnt=(cnt+ask(yy,l,r))%mod;
	return cnt;
}
signed main()
{
	//freopen("1.in","r",stdin);
	get(n);INV2=ksm(2,phi-1);
	//cout<<3*5*7*11*13*17*19*23<<endl;
	//cout<<2*4*6*10*12*16*18*22<<endl;
	//cout<<2*INV2%mod<<endl;
	rep(1,n,i)get(a[i]);
	build(1,1,n);
	get(Q);
	rep(1,Q,i)
	{
		ll op,l,r,m,d;
		get(op);get(l);get(r);get(m);
		if(op==1)get(d),change(1,l,r,m),modify(1,l+1,r,0,d);
		else putl(ask(1,l,r)%m);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/chdy/p/12728545.html