• 【洛谷5472】[NOI2019] 斗主地(猜结论)


    点此看题面

    • 有一个(n)张牌的牌堆,初始从上往下依次编号(1sim n),编号为(i)的牌的权值为(x^{ty})
    • (m)轮洗牌,第(i)次会先将牌堆最上面(a_i)张牌取出另成一堆。假设当前两堆分别剩余(X,Y)张牌,则会以(frac X{X+Y})的概率取出第一堆最下面的牌,或以(frac Y{X+Y})的概率取出第二堆最下面的牌,放在新牌堆的最上面。
    • (q)次询问,每次询问最后的第(i)张牌权值的期望。
    • (nle10^7,mle5 imes10^5,ty=1 or 2)

    非常玄学的猜结论题

    这道题的核心结论:一次函数洗牌之后的期望还是一次函数,二次函数洗牌后的期望还是二次函数

    证明暂且不会,先坑了。(话说如果真在考场上遇到这种题目,真不知道自己有没有猜结论并相信自己的结论的自信。。。)

    如果这个结论是正确的,那么(m)次洗牌之后得到的仍应是一次函数/二次函数,也就是说我们只要任选三个好算的位置算一算就好了。

    首先第一个位置和最后一个位置肯定是很好算的,那么我们再添上第二个位置就凑齐三个位置了。

    转移很显然:

    [x_1=x_1 imes frac an+x_{a+1} imesfrac {n-a}n\ x_n=x_a imesfrac an+x_n imesfrac{n-a}n\ x_2=x_2 imesfrac{a-1}{n-1} imesfrac an+x_{a+1} imesfrac{n-a}{n-1} imesfrac an+x_{1} imesfrac{a}{n-1} imesfrac{n-a}n+x_{a+2} imesfrac{n-a-1}{n-1} imesfrac{n-a}n ]

    发现分母实际上只有(n)(frac1{(n-1)n}),可以实现预处理避免复杂度平添一个(log)

    而要由三个值解出一个二次函数,只要列出三个方程:

    [egin{cases} A+B+C=x_1,\ 4A+2B+C=x_2,\ n^2A+nB+C=x_n end{cases} Rightarrow egin{cases} A=frac{(n-2)x_1-(n-1)x_2+x_n}{n^2-3n+2},\ B=x_2-x_1-3A,\ C=x_1-A-B end{cases} ]

    分母同样可以预处理。

    所以说这道题的难点就在于最开始洗牌之后函数次数不变的结论,之后的过程真就超级简单了。

    代码:(O(m+q))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define X 998244353
    using namespace std;
    int n,m,ty;I int QP(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;} 
    namespace FastIO
    {
    	#define FS 100000
    	#define tc() (FA==FB&&(FB=(FA=FI)+fread(FI,1,FS,stdin),FA==FB)?EOF:*FA++)
    	#define pc(c) (FC==FE&&(clear(),0),*FC++=c)
    	int OT;char oc,FI[FS],FO[FS],OS[FS],*FA=FI,*FB=FI,*FC=FO,*FE=FO+FS;
    	I void clear() {fwrite(FO,1,FC-FO,stdout),FC=FO;}
    	Tp I void read(Ty& x) {x=0;W(!isdigit(oc=tc()));W(x=(x<<3)+(x<<1)+(oc&15),isdigit(oc=tc()));}
    	Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
    	Tp I void writeln(Ty x) {W(OS[++OT]=x%10+48,x/=10);W(OT) pc(OS[OT--]);pc('
    ');}
    }using namespace FastIO;
    int A,B,C;I int F(CI x) {return (1LL*A*x%X*x+1LL*B*x+C)%X;}//计算F(x)的值
    int IV;I void Calc(CI x,CI y,CI z) {A=(1LL*(n-2)*x%X-1LL*(n-1)*y%X+z+X)*IV%X,B=(y-x-3LL*A+4LL*X)%X,C=(x-A-B+2LL*X)%X;}//解方程
    int main()
    {
    	read(n,m,ty);RI iv=QP(n,X-2),iv_=1LL*iv*QP(n-1,X-2)%X;IV=QP((1LL*n*n-3*n+2)%X,X-2);//预处理分母
    	RI i,a,x=1,y=QP(2,ty),z=QP(n,ty);for(i=1;i<=m;++i) read(a),Calc(x,y,z),//求出二次函数
    		x=(1LL*F(1)*a+1LL*F(a+1)*(n-a))%X*iv%X,z=(1LL*F(a)*a+1LL*F(n)*(n-a))%X*iv%X,//求出新的x1,xn
    		y=((1LL*F(2)*(a-1)+1LL*F(a+1)*(n-a))%X*a+(1LL*F(1)*a+1LL*F(a+2)*(n-a-1))%X*(n-a))%X*iv_%X;//求出新的x2
    	RI Qt;read(Qt),Calc(x,y,z);W(Qt--) read(a),writeln(F(a));return clear(),0;//代入函数中计算值
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    python基础语法_9-2函数式编程
    python基础语法_9-1闭包 装饰器补充
    python基础语法_9-0函数概念
    python基础语法_8循环语句
    python基础语法_7运算符
    python基础语法_3面向对象
    python基础语法_2基本数据类型
    python基础语法_python中的布尔类型详解
    用户需求分析
    结对编程-词频统计(北航暑期软工培训) 郑琪 李泓毅
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu5472.html
Copyright © 2020-2023  润新知