多校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)

线段树维护。

image

fib可以在O(1)时间内计算出某项的数值还有和值,只要写成点对和的形式:

fib8=fib7+fib6
=2fib6+fib5
=3
fib5+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;
}

posted on 2022-08-20 16:25  HZOI-曹蓉  阅读(55)  评论(2)    收藏  举报