多校13
rank 39 mark 140
T2:概率期望
T2:你在k维的坐标系中,从(1,1,...)到(n1,n2,n2...),每次你有p的概率逼近终点一步,(1-p)的概率回退到走到当前位置的上一个状态,求走到终点的步数期望.(n<=1e5)
(1)显然倒退的话dp[i]:从i到终点的期望时间dp[i]=dp[i-1](1-p)+dp[i+1]p+1.(显然和维度没有关系对吧)发现i和前后都有关系,正推和倒推都不行,于是都列出来,用f1=f2+1,f2=f1(1-p)+f3(p)+1,....把fx表示成f(x)=f(x+1)+Bx的形式,最后f(step)=f(step+1)+Bstep,f(step+1)=0.就可以回退过去,把f(0)求出来。
from Soytony%%%(推导过程)
https://www.luogu.com.cn/paste/bocyurtx
(2)正推:dp[x]:表示从x走到下一步的期望步数,如果直接过去,是p1,如果退回去,还必须花费1的步数再走到x+1,是(dp[x-1]+d[x]+1)(1-p).
int t;
int k,sgmn;ll p,_p;
ll dp[N*5];
inline ll qpow(ll a,ll b)
{
ll sd=1;
while(b)
{
if(b&1){sd=sd*a%mod;}
b>>=1;a=a*a%mod;
}
return sd;
}
int main()
{
//freopen("1.in","r",stdin);
// freopen("a.txt","w",stdout);
t=re();
_f(qwertyuiop,1,t)
{
_f(i,0,sgmn)dp[i]=0;
k=re();sgmn=0;
_f(i,1,k)sgmn+=re()-1;
p=re();_p=(1-p+mod)%mod;ll np=qpow(p,mod-2)*_p%mod;
dp[0]=1;
_f(i,1,sgmn)dp[i]=(1+np*(dp[i-1]+1)%mod)%mod;
//chu("dp[%d]:%lld\n",0,dp[0]);
//chu("dp[%d]:%lld\n",1,dp[1]);
ll ans=0;
_f(i,0,sgmn-1)ans=(ans+dp[i])%mod;
chu("%lld\n",ans);
}
return 0;
}
T3:给你一个数列,支持(1)区间加上一段k为首项的等差数列,公差是d(2)加上一段首项是k的等比数列,首项k(3)加上一段从1开始的fib数列(4)区间查询和值(N<=1e5)
线段树维护。

fib可以在O(1)时间内计算出某项的数值还有和值,只要写成点对和的形式:
fib8=fib7+fib6
=2fib6+fib5
=3fib5+2fib4
发现fib(A+len-1)=f1[len]fib(X)+f2[len]fib(X-1)
f1:1 0 1 1 2
f2:0 1 1 2
让我想想我这个大马虎鬼都干了些什么(1)l-r+1(2)fib从0开始算但是下标从1开始计数(3)pushdonw只清空了tag,没有清空信息数组cd,jk,jd
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<deque>
#include<queue>
#include<map>
#include<bitset>
#include<set>
#include<ctime>
using namespace std;
#define _f(i,a,b) for(register int i=a;i<=b;++i)
#define f_(i,a,b) for(register int i=a;i>=b;--i)
#define rint register int
#define ll long long
#define chu printf
#define INF 2147483647
inline ll re()
{
ll x=0,h=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')h=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*h;
}
const int N=1e5+10;const ll mod=19260817,ny2=9630409;
int n,m;
ll D;
int tag1[N<<2],tag2[N<<2],tag3[N<<2],a[N];
ll jk[N<<2],jd[N<<2],ck[N<<2],g[N],sumg[N],h1[N<<2],
h2[N<<2],sum[N<<2];//就是累计的标记
//等差的首项,公差,等比的首项,fib的首项,次项,区间的和值
ll f1[N],f2[N],sumf1[N],sumf2[N];
inline void preworkcanyoudo()
{
f1[1]=f2[2]=1;
_f(i,3,n)f1[i]=(f1[i-1]+f1[i-2])%mod,f2[i]=(f2[i-1]+f2[i-2])%mod;
_f(i,1,n)sumf1[i]=(sumf1[i-1]+f1[i])%mod,sumf2[i]=(sumf2[i-1]+f2[i])%mod;
g[1]=1;sumg[1]=1;
_f(i,2,n)g[i]=g[i-1]*D%mod,sumg[i]=(sumg[i-1]+g[i])%mod;
}
#define lson (rt<<1)
#define rson ((rt<<1)|1)
inline void pushup(int rt)
{sum[rt]=(sum[lson]+sum[rson])%mod;return;}
inline void build(int rt,int l,int r)
{
if(l==r){sum[rt]=a[l]%mod;return;}//这里也取%
int mid=(l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(rt);
}
inline ll calc(ll st,ll len,ll cha)
{
return (st+st+(len-1)*cha)%mod*len%mod*ny2%mod;
}
inline void add1(int rt,int l,int r,int L,int R,ll k,ll d)//l,r是要全部更新的
//L l r R
{
k=(k+d*(l-L))%mod;
sum[rt]=(sum[rt]+calc(k,r-l+1,d))%mod;//这写反了
jk[rt]=(jk[rt]+k)%mod;
jd[rt]=(jd[rt]+d)%mod;
tag1[rt]=1;
}
inline void add2(int rt,int l,int r,int L,int R,ll k)
{
k=k*g[l-L+1]%mod;
sum[rt]=(sum[rt]+sumg[r-l+1]*k%mod)%mod;
ck[rt]=(ck[rt]+k)%mod;
tag2[rt]=1;
}
inline void add3(int rt,int l,int r,int L,int R,int x,int y)
{
if(l==r)
{
sum[rt]=(sum[rt]+x*f1[l-L+1]%mod+y*f2[l-L+1]%mod)%mod;
//chu("(%d--%d(should %d %d))(x:%d y:%d)sum:%d:%lld\n",l,r,L,R,x,y,rt,sum[rt]);
return;
}
ll res1=(x*f1[l-L+1]%mod+y*f2[l-L+1]%mod)%mod;
//chu("之前起点是:%d 现在到:%d x由:%d 变成:%d\n",L,l,x,res1);
ll res2=(x*f1[l-L+2]%mod+y*f2[l-L+2]%mod)%mod;
// chu("之前起点是:%d 现在到:%d x由:%d 变成:%d\n",L,l,y,res2);
// chu("lasttsum[%d]:%d\n",rt,sum[rt]);
// chu("sum1:%lld sum2:%lld\n",sumf1[r-l+1],sumf2[r-l+1]);
sum[rt]=(sum[rt]+res1*sumf1[r-l+1]%mod+res2*sumf2[r-l+1]%mod)%mod;
// chu("sum[%d]:%d\n",rt,sum[rt]);
tag3[rt]=1;
h1[rt]=(h1[rt]+res1)%mod;h2[rt]=(h2[rt]+res2)%mod;//首项和次首项的累加
}
inline void pushdown1(int rt,int l,int r)
{
int mid=(l+r)>>1;
add1(lson,l,mid,l,r,jk[rt],jd[rt]);tag1[rt]=0;
add1(rson,mid+1,r,l,r,jk[rt],jd[rt]);
jk[rt]=jd[rt]=0;
}
inline void pushdown2(int rt,int l,int r)
{
int mid=(l+r)>>1;
add2(lson,l,mid,l,r,ck[rt]);tag2[rt]=0;
add2(rson,mid+1,r,l,r,ck[rt]);
ck[rt]=0;//清空!
}
inline void pushdown3(int rt,int l,int r)
{
int mid=(l+r)>>1;
add3(lson,l,mid,l,r,h1[rt],h2[rt]);tag3[rt]=0;
add3(rson,mid+1,r,l,r,h1[rt],h2[rt]);
h1[rt]=h2[rt]=0;
}
inline void update1(int rt,int l,int r,int L,int R,ll k,ll d)
{
if(L<=l&&r<=R){add1(rt,l,r,L,R,k,d);return;}
int mid=(l+r)>>1;
if(tag1[rt])pushdown1(rt,l,r);
if(tag2[rt])pushdown2(rt,l,r);
if(tag3[rt])pushdown3(rt,l,r);
if(L<=mid)update1(lson,l,mid,L,R,k,d);
if(R>mid)update1(rson,mid+1,r,L,R,k,d);
pushup(rt);
}
inline void update2(int rt,int l,int r,int L,int R,ll k)
{
if(L<=l&&r<=R){add2(rt,l,r,L,R,k);return;}
int mid=(l+r)>>1;
if(tag1[rt])pushdown1(rt,l,r);
if(tag2[rt])pushdown2(rt,l,r);
if(tag3[rt])pushdown3(rt,l,r);
if(L<=mid)update2(lson,l,mid,L,R,k);
if(R>mid)update2(rson,mid+1,r,L,R,k);
pushup(rt);
}
inline void update3(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R){add3(rt,l,r,L,R,1,1);return;}
int mid=(l+r)>>1;
if(tag1[rt])pushdown1(rt,l,r);
if(tag2[rt])pushdown2(rt,l,r);
if(tag3[rt])pushdown3(rt,l,r);
if(L<=mid)update3(lson,l,mid,L,R);
if(R>mid)update3(rson,mid+1,r,L,R);
pushup(rt);
}
inline ll query(int rt,int l,int r,int L,int R)
{
//chu("%d %d %d %d %d\n",rt,l,r,L,R);
if(L<=l&&r<=R)
{
//chu("query:(%d %d)sum[%d]:%lld\n",l,r,rt,sum[rt]);
return sum[rt];
}
int mid=(l+r)>>1;
if(tag1[rt])pushdown1(rt,l,r);
if(tag2[rt])pushdown2(rt,l,r);
if(tag3[rt])pushdown3(rt,l,r);
ll ans=0;
if(L<=mid)ans=(ans+query(lson,l,mid,L,R))%mod;
if(R>mid)ans=(ans+query(rson,mid+1,r,L,R))%mod;
pushup(rt);
//chu("return the ans:%lld\n",ans);
return ans;
}
inline void solve1()
{
int l=re(),r=re(),k=re(),d=re();
update1(1,1,n,l,r,k,d);
}
inline void solve2()
{
int l=re(),r=re(),k=re();
update2(1,1,n,l,r,k);
}
inline void solve3()
{
int l=re(),r=re();
update3(1,1,n,l,r);
}
inline void solve4()
{
int l=re(),r=re();
//chu("i want query:%d %d\n",l,r);
// chu("sum[4]:%lld\n",sum[4]);
chu("%lld\n",query(1,1,n,l,r));
}
int main()
{
//freopen("1.in","r",stdin);
//freopen("a.txt","w",stdout);
n=re();m=re(),D=re();
_f(i,1,n)a[i]=re();
preworkcanyoudo();
build(1,1,n);
_f(i,1,m)
{
int opt=re();
if(opt==1)solve1();
else if(opt==2)solve2();
else if(opt==3)solve3();
else solve4();
}
return 0;
}
浙公网安备 33010602011771号