zoukankan      html  css  js  c++  java
  • ●BZOJ 1416 [NOI2006]神奇的口袋

    题链:

    http://www.lydsy.com/JudgeOnline/problem.php?id=1416
    题解:

    Pòlya瓦罐模型:
    给定罐子里每种颜色的球的个数A[i],按题目要求随机操作若干次之后,摸到i号球的概率仍然为A[i]/sum(A[i])。

    所以可以把题目看成若干次这种游戏,得出每次取球时的概率,然后更新对应的A[i]和sum(A[i])。
    把每次的概率相乘即是答案。

    要用到高精度,为了避免除法,可以先把分子分母质因数分解(最大质因子不超过20000),
    把分子分母相同的因子相互抵消后,再用高精度乘起来。


    代码:

    #include<bits/stdc++.h>
    #define BIT 10000
    #define MAXN 1005
    using namespace std;
    struct Bigint{
    	int A[2*MAXN],len;
    	Bigint(){memset(A,0,sizeof(A)); len=1;}
    	void operator = (int rtm){
    		*this=Bigint();
    		do{
    			A[len++]=rtm%BIT; rtm/=BIT;
    		}while(rtm);
    		len--;
    	}
    	Bigint operator * (const Bigint &rtm) const{
    		static Bigint now; now=Bigint();
    		for(int i=1;i<=len;i++)
    			for(int j=1;j<=rtm.len;j++){
    				now.A[i+j-1]+=A[i]*rtm.A[j];
    				now.A[i+j]+=now.A[i+j-1]/BIT;
    				now.A[i+j-1]%=BIT;
    			}
    		now.len=len+rtm.len;
    		while(!now.A[now.len]) now.len--;
    		return now;
    	}
    	Bigint operator ^ (int b){
    		static Bigint now,base;
    		base=*this; now=1;
    		while(b){
    			if(b&1) now=now*base;
    			b>>=1; base=base*base;
    		}
    		return now;
    	}
    	void Print(){
    		printf("%d",A[len]);
    		for(int i=len-1;i;i--)
    			printf("%04d",A[i]);
    	}
    };
    int T,N,D,S,pnt;
    int A[MAXN],prime[20005],cnt[2][20005];
    void prework(){
    	static bool np[20005];
    	for(int i=2;i<=20000;i++) if(!np[i]){
    		prime[++pnt]=i; 
    		for(int j=i*i;j<=20;j+=i) np[j]=1;
    	}
    }
    void Decomposition(int k,int val){
    	static int mincnt;
    	if(val&&cnt[k][0]!=0) cnt[k][0]=1;
    	else return (void)(cnt[k][0]=0);
    	for(int i=1;i<=pnt&&val!=1;i++){
    		while(val%prime[i]==0)
    			cnt[k][i]++,val/=prime[i];
    		mincnt=min(cnt[k][i],cnt[k^1][i]);
    		cnt[k][i]-=mincnt; cnt[k^1][i]-=mincnt;
    	}
    }
    Bigint combination(int k){
    	Bigint ret,tmp; ret=cnt[k][0];
    	for(int i=0;i<=pnt;i++) if(cnt[k][i]){
    		tmp=prime[i];
    		tmp=tmp^cnt[k][i];
    		ret=ret*tmp;
    	}
    	return ret;
    }
    int main(){
    	prework(); prime[0]=1;
    	cnt[0][0]=cnt[1][0]=-1;
    	scanf("%d%d%d",&T,&N,&D);
    	for(int i=1;i<=T;i++)
    		scanf("%d",&A[i]),S+=A[i];
    	for(int i=1,x,y;i<=N;i++){
    		scanf("%d%d",&x,&y);
    		Decomposition(0,A[y]);
    		Decomposition(1,S);
    		A[y]+=D; S+=D;
    	}
    	Bigint a=combination(0);
    	Bigint b=combination(1);
    	if(!cnt[0][0]) b=1;
    	a.Print(); putchar('/');
    	b.Print(); putchar('
    ');
    	return 0;
    }
    

      

  • 相关阅读:
    boke
    Http post/get
    记一次网站优化---图片压缩与移动端画面缩放问题
    深入浅出 Vue.js 第九章 解析器---学习笔记
    Linux/Mac中alias的使用
    JavaScript中的函数柯里化与反柯里化
    JavaScript中深拷贝实现
    JavaScript中的节流和防抖
    博客园加入百度统计遇到的坑
    记一次无数据库下动态更新文案的解决历程
  • 原文地址:https://www.cnblogs.com/zj75211/p/8541917.html
Copyright © 2011-2022 走看看