zoukankan      html  css  js  c++  java
  • Bzoj1498&1416: [NOI2006]神奇的口袋

    什么鬼双倍经验题???


    Sol

    考虑在第(k)次摸到(y)的概率

    • 如果上次摸到(y),目前有(sum)个球,(y)(a[y])个,那么概率就是(frac{a[y]+d}{sum+d}*frac{a[y]}{sum})
    • 如果上次没摸到(y),那么概率就是(frac{a[y]}{sum+d}*frac{sum-a[y]}{sum})

    合在一起就是(frac{a[y]}{sum})

    那么就是直接这样写

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    const int _(2005);
    typedef long long ll;
    
    IL int Input(){
        RG int x = 0, z = 1; RG char c = getchar();
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    int t, n, d, a[_], sum;
    ll p1 = 1, p2 = 1;
    
    IL ll Gcd(RG ll x, RG ll y){
        return !y ? x : Gcd(y, x % y);
    }
    
    int main(RG int argc, RG char* argv[]){
        t = Input(), n = Input(), d = Input();
        for(RG int i = 1; i <= t; ++i) a[i] = Input(), sum += a[i];
        for(RG int i = 1, y; i <= n; ++i){
            Input(), y = Input();
            p1 *= a[y], p2 *= sum;
            sum += d, a[y] += d;
        }
        RG ll d = Gcd(p1, p2);
        printf("%lld/%lld
    ", p1 / d, p2 / d);
        return 0;
    }
    

    然后显然要高精度,为防止高精度(Gcd)
    所以可以直接分解质因数,然后乘法

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    const int _(2005);
    const int __(2e5 + 1);
    const int SZ(1e4);
    typedef long long ll;
    
    IL int Input(){
        RG int x = 0, z = 1; RG char c = getchar();
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    int t, n, d, a[_], sum;
    int prime[__], num, isprime[__];
    struct Int{
    	int fac[__], len, a[__];
    
    	IL void Add(RG int x){
    		for(RG int i = 1; i <= num && prime[i] <= x; ++i)
    			while(!(x % prime[i])) x /= prime[i], ++fac[i];
    	}
    
    	IL void Mul(RG int x){
    		RG int ud = 0;
    		for(RG int i = 1; i <= len; ++i)
    			a[i] = a[i] * x + ud, ud = a[i] / SZ, a[i] %= SZ;
    		while(ud) a[++len] = ud % SZ, ud /= SZ;
    	}
    
    	IL void Print(){
    		printf("%d", a[len]);
    		for(RG int i = len - 1; i; --i) printf("%04d", a[i]);
    	}
    } P1, P2;
    
    IL void Sieve(){
    	isprime[1] = 1;
    	for(RG int i = 2; i < __; ++i){
    		if(!isprime[i]) prime[++num] = i;
    		for(RG int j = 1; j <= num && i * prime[j] < __; ++j){
    			isprime[i * prime[j]] = 1;
    			if(!(i % prime[j])) break;
    		}
    	}
    }
    
    int main(RG int argc, RG char* argv[]){
    	Sieve(), P1.len = P2.len = P1.a[1] = P2.a[1] = 1;
    	t = Input(), n = Input(), d = Input();
    	for(RG int i = 1; i <= t; ++i) a[i] = Input(), sum += a[i];
    	for(RG int i = 1, y; i <= n; ++i){
    		Input(), y = Input();
    		if(!a[y]) return puts("0/1"), 0;
    		P1.Add(a[y]), P2.Add(sum);
    		sum += d, a[y] += d;
    	}
    	for(RG int i = 1; i <= num; ++i){
    		if(P2.fac[i] >= P1.fac[i]) P2.fac[i] -= P1.fac[i], P1.fac[i] = 0;
    		else P1.fac[i] -= P2.fac[i], P2.fac[i] = 0;
    		for(RG int j = 1; j <= P1.fac[i]; ++j) P1.Mul(prime[i]);
    		for(RG int j = 1; j <= P2.fac[i]; ++j) P2.Mul(prime[i]);
    	}
    	P1.Print(), putchar('/'), P2.Print();
        return puts(""), 0;
    }
    
  • 相关阅读:
    Android,资料分享(2015 版)
    Http请求与响应
    SpringMVC + Spring 3.2.14 + Hibernate 3.6.10 集成详解
    ORA-14402: 更新分区关键字列将导致分区的更改
    Android Service的生命周期
    Android Service基础
    Android Intent 基本使用及对象构成
    Sublime Text3 个人使用心得
    深入了解line-height
    overflow之锚点技术实现选项卡
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8708082.html
Copyright © 2011-2022 走看看