zoukankan      html  css  js  c++  java
  • 【洛谷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;//代入函数中计算值
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    linux查看CPU和内存信息
    linux yum命令详解
    查看文件中关键字前后几行的内容
    vue.js+web storm安装及第一个vue.js
    android GPS: code should explicitly check to see if permission is available
    ASP.NET MVC Identity 使用自己的SQL Server数据库
    阿里云服务器,tomcat启动,一直卡在At least one JAR was scanned for TLDs yet contained no TLDs就不动了
    ASP.NET MVC4 MVC 当前上下文中不存在名称“Scripts”
    python 将windows字体中的汉字生成图片的方法
    Java android DES+Base64加密解密
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu5472.html
Copyright © 2011-2022 走看看