zoukankan      html  css  js  c++  java
  • CF1172C Nauuo and Pictures 题解

    Codeforces C1
    Codeforces C2
    Luogu C1
    Luogu C2

    Description.

    每张照片有一个权值 \(w_i\),每次第 \(x\) 张照片有 \(\frac{w_x}{\sum_{i=1}^nw_i}\) 的概率被展示。
    每次,如果这张照片被喜欢,那 \(w_i\leftarrow w_i+1\),否则 \(w_i\leftarrow w_i-1\)
    \(m\) 次后每张照片的权值。
    C1 \(n\le 50,m\le 50,w_i\le 50\)
    C2 \(n\le 3\times 10^5,m\le 3000\)

    Solution of C1.

    考虑一个 f[x][i][a][b] 表示初始权值为 \(x\) 的被喜欢的照片,经过 \(i\) 次后期望是什么。
    其中 \(a\) 表示当前喜欢照片总权值,\(b\) 表示当前不喜欢照片的总权值。
    每次转移,f[x][i][a][b] 转移自三个地方:

    1. \(\frac{x}{a+b}\) 的概率转移自 f[x+1][i-1][a+1][b]
    2. \(\frac{a-x}{a+b}\) 的概率转移自 f[x][i-1][a+1][b]
    3. \(\frac{b}{a+b}\) 的概率转移自 f[x][i-1][a][b-1]

    同理,设一个 g[x][i][a][b] 表示不被喜欢的照片

    直接大力转移,复杂度很高,但据说能 AC?

    Solution of C2

    发现一个性质:\(f[x][i][a][b]=f[1][i][a][b]\times x\),严谨证明详见
    感性证明就是初始权值都翻倍了,答案必定翻倍。
    同时,观察转移,我们发现 \(i-b+a\) 一定是定值,可以压掉一维。
    然后就做完了,复杂度 \(O(n+m^2)\)
    我们用 \(f'[a][b]\) 表示 \(f[1][m-a-b][tota+a][totb-b]\)

    Coding.

    点击查看 C2 代码
    //是啊……你就是那只鬼了……所以被你碰到以后,就轮到我变成鬼了……{{{
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<'0'||c>'9';c=getchar()) if(c=='-') f=1;
    	for(;c>='0'&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	if(f) x=-x;
    }/*}}}*/
    const int P=998244353;int n,m,tota,totb,tot;
    int w[200005],f[3005][3005],g[3005][3005];char a[200005];
    inline int ksm(int x,int q=P-2) {int r=1;for(;q;q>>=1,x=1ll*x*x%P) if(q&1) r=1ll*r*x%P;return r;}
    int main()
    {
    	read(n),read(m);for(int i=1;i<=n;i++) read(a[i]);
    	for(int i=1,x;i<=n;i++) read(x),w[i]=x,(a[i]?tota:totb)+=x,tot+=x;
    	for(int i=m;~i;i--)
    	{
    		f[i][m-i]=g[i][m-i]=1;
    		for(int j=min(m-i-1,totb);j>=0;j--)
    			f[i][j]=(1ll*(tota+i+1)*f[i+1][j]+1ll*(totb-j)*f[i][j+1])%P*ksm(i-j+tot)%P,
    			g[i][j]=(1ll*(tota+i)*g[i+1][j]+1ll*(totb-j-1)*g[i][j+1])%P*ksm(i-j+tot)%P;
    	}
    	for(int i=1;i<=n;i++) printf("%lld\n",1ll*w[i]*(a[i]?f[0][0]:g[0][0])%P);
    	return 0;
    }
    
  • 相关阅读:
    Spring--IOC
    神奇的小东西
    视图层发起请求的方式
    jdbc “贾琏欲执事”
    线程的五种状态
    java的<<左移,>>右移,>>>无符号右移
    直接插入排序(单链表排序)
    单链表相关知识以及指针引用相关知识
    将一个数n分解为若干个从小到大排列的质数的积 ,求质数因子
    最小二乘法
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15088930.html
Copyright © 2011-2022 走看看