zoukankan      html  css  js  c++  java
  • 牛客网暑期多校训练营 (第九场)

    A.

    链接:https://www.nowcoder.com/acm/contest/147/A
    来源:牛客网

    题目描述

    Niuniu has recently learned how to use Gaussian elimination to solve systems of linear equations.
    Given n and a[i], where n is a power of 2, let's consider an n x n matrix A.

    The index of A[i][j] and a[i] are numbered from 0.
    The element A[i][j] satisfies A[i][j] = a[i xor j],
    https://en.wikipedia.org/wiki/Bitwise_operation#XOR

    Let p = 1000000007.
    Consider the equation 
    A x = b (mod p)
    where A is an n x n matrix, and x and b are both n x 1 row vector.

    Given n, a[i], b[i], you need to solve the x.
    For example, when n = 4, the equations look like
    A[0][0]*x[0] + A[0][1]*x[1] + A[0][2]*x[2] + A[0][3]*x[3] = b[0] (mod p)
    A[1][0]*x[0] + A[1][1]*x[1] + A[1][2]*x[2] + A[1][3]*x[3] = b[1] (mod p)
    A[2][0]*x[0] + A[2][1]*x[1] + A[2][2]*x[2] + A[2][3]*x[3] = b[2] (mod p)
    A[3][0]*x[0] + A[3][1]*x[1] + A[3][2]*x[2] + A[3][3]*x[3] = b[3] (mod p)
    and the matrix A can be decided by the array a.

    It is guaranteed that there is a unique solution x for these equations.

    输入描述:

    The first line contains an integer, which is n.
    The second line contains n integers, which are the array a.
    The third line contains n integers, which are the array b.

    1 <= n <= 262144
    p = 1000000007
    0 <= a[i] < p
    0 <= b[i] < p

    输出描述:

    The output should contains n lines.
    The i-th(index from 0) line should contain x[i].
    x[i] is an integer, and should satisfy 0 <= x[i] < p.
    示例1

    输入

    复制
    4
    1 10 100 1000
    1234 2143 3412 4321
    

    输出

    复制
    4
    3
    2
    1
    思路分析 : sigma(a[i^j]*x[j]) (0 <= j < n) = b[i] , 因为 i^j^j = i, 所以此式可以变为
     , 然后不就是一个fwt 就可以了
      
      

    代码示例:

     
    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const ll maxn = 3e5+5;
    const ll mod = 1e9+7;
    
    ll n;
    ll a[maxn], b[maxn];
    void fwt(ll *a)
    {
        for(ll d=1;d<n;d<<=1)
            for(ll m=d<<1,i=0;i<n;i+=m)
                for(ll j=0;j<d;j++)
                {
                    ll x=a[i+j],y=a[i+j+d];
                    a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod;
                    //xor:a[i+j]=x+y,a[i+j+d]=x-y;
                    //and:a[i+j]=x+y;
                    //or:a[i+j+d]=x+y;
                }
    }
    
    ll qw(ll a, ll b){
    	ll res = 1;
    	while(b){
    		if (b&1) res = res*a%mod;
    		a = a*a%mod;
    		b >>= 1;
    	}
    	return res;
    }
    
    int main () {
    	cin >> n;
    	
    	for(ll i = 0; i < n; i++){
    		scanf("%lld", &a[i]);
    	}	
    	for(ll i = 0; i < n; i++){
    		scanf("%lld", &b[i]);
    	}
    	fwt(a); fwt(b);
    	for(ll i = 0; i < n; i++){
    		if (a[i] != 0){
    			b[i] = b[i]*qw(a[i], mod-2)%mod;
    		}
    	}
    	fwt(b);
    	for(ll i = 0; i < n; i++){
    		b[i] = b[i]*qw(n, mod-2)%mod;
    		printf("%lld
    ", b[i]);
    	}
    	
    	return 0;
    }
    
    
    

    E .

    链接:https://www.nowcoder.com/acm/contest/147/E
    来源:牛客网

    题目描述
    Niuniu likes to play OSU!
    We simplify the game OSU to the following problem.

    Given n and m, there are n clicks. Each click may success or fail.
    For a continuous success sequence with length X, the player can score X^m.
    The probability that the i-th click success is p[i]/100.
    We want to know the expectation of score.
    As the result might be very large (and not integral), you only need to output the result mod 1000000007.
    输入描述:

    The first line contains two integers, which are n and m.
    The second line contains n integers. The i-th integer is p[i].

    1 <= n <= 1000
    1 <= m <= 1000
    0 <= p[i] <= 100

    输出描述:

    You should output an integer, which is the answer.

    示例1
    输入
    复制

    3 4
    50 50 50

    输出
    复制

    750000020

    说明

    000 0
    001 1
    010 1
    011 16
    100 1
    101 2
    110 16
    111 81

    The exact answer is (0 + 1 + 1 + 16 + 1 + 2 + 16 + 81) / 8 = 59/4.
    As 750000020 * 4 mod 1000000007 = 59
    You should output 750000020.

    备注:

    If you don't know how to output a fraction mod 1000000007,
    You may have a look at https://en.wikipedia.org/wiki/Modular_multiplicative_inverse

    题意 : 有一个长度为 n 的序列,每个位置的可能情况是 0 或 1,并且告诉你每个位置出现 1 的概率是多少, 当一串连续的1在一块时它的得分是 连续 1 的长度的 m 次方,求期望的得分

    思路分析 :

    弱鸡只会一个 n^2 的解法,即相加所有可能的情况的和

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const ll maxn = 1005;
    const ll mod = 1e9+7;
    const ll inv = 570000004;
    
    ll p[maxn];
    ll n, m;
    ll a[maxn][maxn];
    
    void init(){
    	for(ll i = 1; i <= n; i++){
    		a[i][i] = p[i]*inv%mod;
    		for(ll j = i+1; j <= n; j++){
    			a[i][j] = a[i][j-1]*p[j]%mod*inv%mod;
    		}
    	}
    }
    
    ll qw(ll a, ll b){
    	ll res = 1;
    	while(b){
    		if (b&1) res = res*a%mod;
    		a = a*a%mod;
    		b >>= 1;
    	}
    	return res;
    }
    
    int main() {
    	
    	cin >> n >> m;
    	for(ll i = 1; i <= n; i++) {
    		scanf("%lld", &p[i]);	
    	}	
    	init();
    	
    	ll ans = 0;
    	for(ll i = 0; i <= n; i++){
    		for(ll j = i+1; j <= n+1; j++){
    			ans += (100-p[i])*inv%mod*(100-p[j])%mod*inv%mod*a[i+1][j-1]%mod*qw(j-i-1, m)%mod;
    			ans %= mod; 
    		}
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

     但是讲题人有一个 n*m 的解法,用到了斯特林数,表示想了很久还是不太懂,----

    先扔个代码

    #include <bits/stdc++.h>
    using namespace std;
    int n, m, mod = 1000000007;
    long long p[1020];
    long long a[1020];
    long long b[1020];
    long long s[1020][1020];
    long long f[1020];
    int main() {
        scanf("%d%d", &n, &m);
        s[0][0] = 1;
        for (int i = 0; i <= m; i++) {
            for (int j = 1; j <= i; j++) {
                s[i][j] = (s[i - 1][j - 1] + j * s[i - 1][j]) % mod;
            }
        }
        for (int i = f[0] = 1; i <= m; i++) {
            f[i] = f[i - 1] * i % mod;
        }
        for (int i = 1; i <= n; i++) {
            scanf("%lld", &p[i]);
            p[i] = p[i] * 570000004 % mod;
            for (int j = m; j > 0; j--) {
                a[j] += a[j - 1];
                a[j] *= p[i];
                a[j] %= mod;
                b[j] += a[j];
                b[j] %= mod;
            }
            a[0] = p[i];
            b[0] += a[0];
            b[0] %= mod;
        }
        long long z = 0;
        for (int i = 1; i <= m; i++) {
            z = (z + b[i - 1] * f[i] % mod * s[m][i]) % mod;
        }
        printf("%lld
    ", z);
        return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    python学习之字典合并
    python学习之列表、元组、集合、字典随笔
    图像检索中的概念
    卷积、反卷积、转置卷积资源
    计算机视觉顶级会议和期刊
    Week17
    Python协程资源
    深度图像资源
    Geo-localization论文阅读list2
    NetVLAD原理详解和推导
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/9519312.html
Copyright © 2011-2022 走看看