zoukankan      html  css  js  c++  java
  • 6442. 【GDOI2020模拟01.18】钩子

    题目描述

    Description

    Input

    Output

    Sample Input
    Sample Input1
    3 1000000007

    Sample Input2
    4 1000000007

    Sample Output
    Sample Output1
    0 1 0
    500000004 0 500000004
    500000004 0 500000004

    Sample Output2
    0 500000004 500000004 0
    333333336 166666668 166666668 333333336
    333333336 166666668 166666668 333333336
    333333336 166666668 166666668 333333336

    Data Constraint

    题解

    怒刚3h爆0

    可以发现,操作的段可以分成log层,不同层之间段的先后顺序固定,同一层的可以互换

    随便模拟一下可以得到每一层的奇数段数s1和偶数段数s2,考虑计算本层的概率

    (f[i][j])表示已经放了i个奇数段,j个偶数段,那么当前可以放的位置数为((s1-i)+2(s2-j)),每个位置概率相等

    设前面层的总人数为sum,那么在(f[i][j])转移时就轮到第(sum+i+j+1)个人,可以算出每个人放在奇数段和偶数段的概率

    显然放在奇数段的时候每个奇数段被放到的概率相等,所以可以求出第(sum+1sim sum+s1+s2)个人的概率

    往下做时,先假设偶数段只能放左边,做完之后把第(sum+s1+s2+1sim n)个人在偶数段中的对称位置概率平均一下即可

    code

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define add(a,b) a=((a)+(b))%mod
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a>b?a:b)
    //#define file
    using namespace std;
    
    long long f[1001][1001];
    long long g[1001][1001];
    long long h[1002][2]; //0=odd 1=even
    long long w[1001];
    bool bz[1001];
    int g1[21][1002];
    int g2[21][1002];
    int G[21][1002];
    int n,i,j,k,l;
    long long mod,Mod;
    
    long long qpower(long long a,int b)
    {
    	long long ans=1;
    	
    	while (b)
    	{
    		if (b&1)
    		ans=ans*a%mod;
    		
    		a=a*a%mod;
    		b>>=1;
    	}
    	
    	return ans;
    }
    
    void dg(int t,int sum)
    {
    	int i,j,k,l,mx=0,tot=0,s1=0,s2=0;
    	
    	fo(i,1,n) g1[t][i]=!bz[i]?g1[t][i-1]+1:0;
    	fd(i,n,1) g2[t][i]=!bz[i]?g2[t][i+1]+1:0;
    	fo(i,1,n) G[t][i]=min(g1[t][i],g2[t][i]);
    	
    	fo(i,1,n)
    	mx=max(mx,G[t][i]);
    	
    	if (mx==1)
    	{
    		fo(i,1,n) tot+=!bz[i];
    		
    		fo(i,sum+1,n)
    		{
    			fo(j,1,n)
    			if (!bz[j])
    			f[i][j]=w[tot];
    		}
    		
    		return;
    	}
    	
    	fo(i,1,n)
    	if (G[t][i]==mx)
    	{
    		if (G[t][i-1]!=mx && G[t][i+1]!=mx)
    		++s1;
    		else
    		if (G[t][i+1]==mx)
    		++s2;
    	}
    	
    	memset(g,0,sizeof(g));
    	g[0][0]=1;
    	
    	fo(i,0,s1)
    	{
    		fo(j,0,s2)
    		if (i+j<=s1+s2)
    		{
    			if (i<s1)
    			{
    				add(g[i+1][j],g[i][j]*w[(s1-i)+(s2-j)*2]%mod*(s1-i)%mod);
    				add(h[sum+i+j+1][0],g[i][j]*w[(s1-i)+(s2-j)*2]%mod*(s1-i)%mod);
    			}
    			if (j<s2)
    			{
    				add(g[i][j+1],g[i][j]*w[(s1-i)+(s2-j)*2]%mod*((s2-j)*2)%mod);
    				add(h[sum+i+j+1][1],g[i][j]*w[(s1-i)+(s2-j)*2]%mod*((s2-j)*2)%mod);
    			}
    		}
    	}
    	
    	fo(i,sum+1,sum+s1+s2)
    	{
    		fo(j,1,n-1)
    		if (G[t][j]==mx)
    		{
    			if (G[t][j-1]!=mx && G[t][j+1]!=mx)
    			f[i][j]=h[i][0]*w[s1]%mod;
    			else
    			if (G[t][j+1]==mx)
    			{
    				f[i][j]=h[i][1]*w[s2+s2]%mod;
    				f[i][j+1]=h[i][1]*w[s2+s2]%mod;
    			}
    		}
    	}
    	
    	fo(i,1,n)
    	if (G[t][i]==mx && G[t][i-1]!=mx && G[t][i+1]!=mx || G[t][i]==mx && G[t][i+1]==mx)
    	bz[i]=1;
    	
    	dg(t+1,sum+s1+s2);
    	
    	fo(j,1,n-1)
    	if (G[t][j]==mx && G[t][j+1]==mx)
    	{
    		fo(i,sum+s1+s2,n)
    		{
    			fo(k,0,mx-1)
    			{
    				f[i][j-k]=(f[i][j-k]+f[i][j+k+1])*w[2]%mod;
    				f[i][j+k+1]=f[i][j-k];
    			}
    		}
    	}
    }
    
    int main()
    {
    	#ifdef file
    	freopen("a.in","r",stdin);
    	#endif
    	
    	scanf("%d%lld",&n,&mod);Mod=mod-2;
    	
    	w[1]=1;
    	fo(i,2,1000)
    	w[i]=mod-w[mod%i]*(mod/i)%mod;
    	
    	dg(1,0);
    	
    	fo(i,1,n)
    	{
    		fo(j,1,n)
    		printf("%lld ",(f[i][j]+mod)%mod);
    		printf("
    ");
    	}
    }
    
  • 相关阅读:
    Java实现 LeetCode 792 自定义字符串排序(暴力)
    Java实现 LeetCode 792 自定义字符串排序(暴力)
    asp.net session对象的持久化
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    小白也能看懂的约瑟夫环问题
  • 原文地址:https://www.cnblogs.com/gmh77/p/12210937.html
Copyright © 2011-2022 走看看