• [NOI2006]神奇口袋


    题面在这里

    题意

    开始时袋中有(t)种小球,第(i)种小球有(t_i)个,之后每次等概率取出一个球,第(i)次取球时观察这个球的颜色(c_i)放回并向袋中加入(d)个颜色为(c_i)的球;
    给出一组询问([x_i,y_i](1le ile n)),求同时满足第(x_i)次取球的颜色为(y_i)的概率

    (1≤t,n≤1000, 1≤a_k ,d≤10, 1≤x_1<x_2<…<x_n≤10000, 1≤y_k≤t)

    hint

    有没有注意到(1≤x_1<x_2<…<x_n≤10000)这个条件?
    感觉又鬼畜又没有用对么?
    那么我们把这个条件删掉
    其实这个条件仅仅是在给你一个提示

    sol

    其实我做题的时候也不知道这个条件有什么用...于是我就没有做出来
    如果(x_i=i)你还不会做?直接模拟即可

    所以这道题直接模拟就可以了。
    !!!!!!是的很震惊对吧
    给你(1≤x_1<x_2<…<x_n≤10000)这个条件,
    就是让你考虑怎么把这个条件化成(x_i=i)的......

    接下来我们开始证明,
    如果仅仅考虑一次抽取的情况,每次抽到颜色(c)的概率都是一样的,
    即第(i)次抽到颜色(c)的概率和第(i+1)次抽到颜色(c)的概率相同
    设第(i)次抽之前,袋子里总共有(tot)个球,有(a)个颜色为(c)的球(update 4.4:感谢 @GuessYCB的更正 orz)
    那么第(i)次抽抽到(c)的概率显然是(P_i=frac{a}{tot})
    那么第(i+1)次抽抽到(c)的概率呢?

    [P_{i+1}=frac{a}{tot} imesfrac{a+d}{tot+d}+(1-frac{a}{tot}) imesfrac{a}{tot+d}=frac{a}{tot}=P_i ]

    嗯是的

    于是直接把([x_1,x_2,x_3,...,x_n])转换为([1,2,3,...,n])即可
    注意高精(可以考虑先(fact),最后再化系数)

    代码

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define mp make_pair
    #define pb push_back
    #define RG register
    #define il inline
    using namespace std;
    typedef unsigned long long ull;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const dd eps=1e-10;
    const int mod=1e9+7;
    const int N=5010;
    const int M=20010;
    il ll read(){
    	RG ll data=0,w=1;RG char ch=getchar();
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
    	return data*w;
    }
    
    il void file(){
    	//freopen("a.in","r",stdin);
    	//freopen("a.out","w",stdout);
    }
    
    int t,n,d,a[N],y[N],sum;
    int pri[M],vis[M];
    il void sieve(){
    	vis[1]=1;
    	for(RG int i=2;i<M;i++){
    		if(!vis[i])pri[++pri[0]]=i;
    		for(RG int j=1;j<=pri[0]&&1ll*pri[j]*i<M;j++){
    			vis[i*pri[j]]=1;if(i%pri[j]==0)break;
    		}
    	}
    }
    
    int sys[3][M];
    il void fact(int x,int id){
    	for(RG int j=1;j<=pri[0]&&1ll*pri[j]*pri[j]<=x;j++)
    		while(x%pri[j]==0)sys[id][j]++,x/=pri[j];
    	for(RG int j=1;j<=pri[0]&&1ll*pri[j]<=x;j++){
    		while(x%pri[j]==0)sys[id][j]++,x/=pri[j];if(x==1)break;
    	}
    }
    
    struct bignumber{
    	int ws,s[5005];
    	il void init(){ws=s[1]=1;}
    	il void times(int x){
    		if(!ws)init();
    		for(RG int i=1;i<=ws;i++)s[i]*=x;
    		for(RG int i=1;i<=ws;i++)
    			if(s[i]>=10)s[i+1]+=s[i]/10,s[i]%=10;
    		while(s[ws+1])ws++,s[ws+1]+=s[ws]/10,s[ws]%=10;
    	}
    	il void print(){
    		for(RG int i=ws;i;i--)printf("%d",s[i]);
    	}
    }A[3];
    
    il void solve(){
    	for(RG int i=1,minn;i<=pri[0];i++){
    		minn=min(sys[1][i],sys[2][i]);
    		sys[1][i]-=minn;sys[2][i]-=minn;
    	}
    	A[1].init();A[2].init();
    	for(RG int id=1;id<=2;id++)
    		for(RG int i=1;i<=pri[0];i++)
    			for(RG int j=1;j<=sys[id][i];j++)A[id].times(pri[i]);
    	A[2].print();printf("/");A[1].print();puts("");
    }
    
    int main()
    {
    	t=read();n=read();d=read();sieve();
    	for(RG int i=1;i<=t;i++)a[i]=read(),sum+=a[i];
    	for(RG int i=1;i<=n;i++)
    		read(),y[i]=read(),fact(a[y[i]],2),a[y[i]]+=d,fact(sum,1),sum+=d;
    	solve();return 0;
    }
    
  • 相关阅读:
    How much training data do you need?
    什么样的论文容易接收发表?​
    How to Write and Publish a Scientific Paper: 7th Edition(科技论文写作与发表教程)(11.04更新)
    如何起草你的第一篇科研论文——应该做&避免做
    Writing the first draft of your science paper — some dos and don’ts
    matlab学习笔记 bsxfun函数
    乘法器的Verilog HDL实现
    重构:改善既有代码的设计
    【Leetcode】Length of Last Word
    Saving HDU hdu
  • 原文地址:https://www.cnblogs.com/cjfdf/p/8463649.html
Copyright © 2020-2023  润新知