码迷,mamicode.com
首页 > 其他好文 > 详细

模拟9题解

时间:2019-07-29 09:18:10      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:pow   view   复杂度   模拟   main   style   ace   src   c++   

T1随(rand)「概率和期望」「动态规划」

昨天误删了两篇博客QAQ

所以直接写正解了:

此T1实则为T3

由1<=ai<mod,且x=x*ai%mod 得 1<=任意状态<mod

定义f[i][j]为到第i位的当前状态为j的方案数

可得$f[i*2][j*k\%mod]=f[i][j]*f[i][k]$,

考虑对m进行优化

考虑快速幂的思想,a^b%c

f数组为a,m为b,定义g数组为ans

g[i][j]为累计到m的二进制第i位的状态为j的方案数

$g[2^a+2^b+2^c][j*k\%mod]=g[2^a+2^b][j]*f[2^c][k]$

时间复杂度O(log(m)mod^2)

因为f和g的转移只与第一维的上一位有关,滚动起来优化空间

技术图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #define int long long
 6 using namespace std;
 7 const int modd=1e9+7;
 8 int read()
 9 {
10     int f=1,x=0;char ch=getchar();
11     while(ch>9||ch<0){if(ch==-)f=-1;ch=getchar();}
12     while(ch<=9&&ch>=0){x=(x<<3)+(x<<1)+ch-0;ch=getchar();}
13     return f*x;
14 }
15 int n,m,p,a[100005],t[1005];
16 int f[3][1005],g[3][1005];
17 int qpow(int a,int b,int c)
18 {
19     int ans=1;
20     while(b)
21     {
22         if(b&1)  ans=ans*a%c;
23         b>>=1;
24         a=a*a%c;
25     }
26     return ans%c;
27 }
28 signed main()
29 {
30     n=read(),m=read(),p=read();
31     for(int i=1;i<=n;i++)
32         a[i]=read(),t[a[i]]++;
33     if(n==1)
34     {
35         int ans=qpow(a[1],m,p);
36         printf("%lld\n",ans%modd);
37         return 0;
38     }
39     if(p==2)
40     {
41         puts("1");
42         return 0;
43     }
44     m--;
45     f[0][1]=1;
46     for(int j=1;j<p;j++)
47         for(int k=1;k<p;k++)
48             f[1][j*k%p]+=f[0][j]*t[k]%modd,f[1][j*k%p]%=modd;
49     for(int j=1;j<p;j++)
50         g[0][j]=f[1][j];
51     int cnt=1,cnt2=0;
52     while(m)
53     {
54         if(m&1)
55         {
56             cnt2^=1;
57             memset(g[cnt2],0,sizeof g[cnt2]);
58             for(int j=1;j<p;j++)
59                 for(int k=1;k<p;k++)
60                     g[cnt2][j*k%p]+=g[cnt2^1][j]*f[cnt][k]%modd,g[cnt2][j*k%p]%=modd;
61         }
62         cnt^=1;
63         memset(f[cnt],0,sizeof f[cnt]);
64         for(int j=1;j<p;j++)
65             for(int k=1;k<p;k++)
66                 f[cnt][j*k%p]+=f[cnt^1][j]*f[cnt^1][k]%modd,f[cnt][j*k%p]%=modd;
67         m>>=1;
68     }
69     int a1=0,a2=0;
70     for(int j=1;j<p;j++){
71         a1=(a1+j*g[cnt2][j]%modd)%modd;
72         a2=(a2+g[cnt2][j])%modd;
73     }
74     int ans=a1*qpow(a2,modd-2,modd)%modd;
75     printf("%lld\n",ans%modd);
76 }
View Code

T2 单(single)

t=0:

暴力预处理出b[1],1为根,

dfs处理sum[x],sum[x]为x的子树大小

在树上,x与其父亲fa的转移关系:

b[x]=b[fa]+sum[1]-2*sum[x]

dfs O(n)转移

t=1:

将上式变形,

b[x]-b[fa]=sum[1]-2*sum[x]

n-1(除了x=1)个式子相加

左式为定值,右=(n-1)sum[1]-2*Σ(sum[2]+……sum[n])

Σ(sum[2]+……sum[n])=b[1]

求的sum[1]后代回求解

 

技术图片
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<vector>
  5 #include<cmath>
  6 #include<queue>
  7 #define int long long
  8 using namespace std;
  9 const int maxn=100005;
 10 int read(){
 11     int f=1,x=0;char ch=getchar();
 12     while(ch>9||ch<0){if(ch==-)f=-1;ch=getchar();}
 13     while(ch<=9&&ch>=0){x=(x<<3)+(x<<1)+ch-0;ch=getchar();}
 14     return f*x;
 15 }
 16 int n,a[maxn],b[maxn],h[maxn],nu,d[maxn],fa[maxn];
 17 struct node{int v,nxt;}e[2*maxn];
 18 void add(int x,int y){e[++nu].v=y;e[nu].nxt=h[x];h[x]=nu;}
 19 void bfs()
 20 {
 21     queue<int>q;
 22     d[1]=1;
 23     q.push(1);
 24     while(q.size())
 25     {
 26         int x=q.front();q.pop();
 27         for(int i=h[x];i;i=e[i].nxt)
 28         {
 29             int y=e[i].v;
 30             if(d[y])continue;
 31             q.push(y);
 32             d[y]=d[x]+1;
 33             fa[y]=x;
 34         }
 35     }
 36 }
 37 bool v[maxn];int sum[maxn];
 38 void dfs1(int x)
 39 {
 40     v[x]=1;
 41     sum[x]=a[x];
 42     for(int i=h[x];i;i=e[i].nxt)
 43     {
 44         int y=e[i].v;
 45         if(v[y])continue;
 46         dfs1(y);
 47         sum[x]+=sum[y];
 48     }
 49 }
 50 void dfs2(int x)
 51 {
 52     v[x]=1;
 53     for(int i=h[x];i;i=e[i].nxt)
 54     {
 55         int y=e[i].v;
 56         if(v[y])continue;
 57         b[y]=b[x]+sum[1]-2*sum[y];
 58         dfs2(y);
 59     }
 60 }
 61 void dfs3(int x)
 62 {
 63     v[x]=1;
 64     for(int i=h[x];i;i=e[i].nxt)
 65     {
 66         int y=e[i].v;
 67         if(v[y])continue;
 68         sum[x]-=sum[y];
 69         dfs3(y);
 70     }
 71     a[x]=sum[x];
 72 }
 73 void init()
 74 {
 75     nu=0;
 76     memset(e,0,sizeof e);
 77     memset(h,0,sizeof h);
 78     memset(a,0,sizeof a);
 79     memset(b,0,sizeof b);
 80     memset(d,0,sizeof d);
 81     memset(sum,0,sizeof sum);
 82 }
 83 signed main()
 84 {
 85     int T=read();
 86     while(T--)
 87     {
 88         init();
 89         n=read();
 90         for(int i=1;i<n;i++)
 91         {
 92             int x=read(),y=read();
 93             add(x,y),add(y,x);
 94         }
 95         bfs();    
 96         int tt=read();
 97         if(tt==0)
 98         {
 99             for(int i=1;i<=n;i++)   a[i]=read();
100             for(int i=1;i<=n;i++)
101                 b[1]+=a[i]*(d[i]-d[1]);
102             memset(v,0,sizeof v);
103             dfs1(1);
104             memset(v,0,sizeof v);
105             dfs2(1);
106             for(int i=1;i<=n;i++)
107                 printf("%d ",b[i]);
108         }
109         else
110         {
111             for(int i=1;i<=n;i++) b[i]=read();
112             int tot=0;
113             for(int i=2;i<=n;i++)
114                 tot+=(b[i]-b[fa[i]]);
115             sum[1]=(tot+2*b[1])/(n-1);
116             for(int i=2;i<=n;i++)
117                 sum[i]=(sum[1]-b[i]+b[fa[i]])/2;
118             memset(v,0,sizeof v);
119             dfs3(1);
120             for(int i=1;i<=n;i++)
121                 printf("%d ",a[i]);
122         }
123         puts("");
124     }
125 }
View Code

 

T3 题(problem)

typ==1时为catalan数,可以看成括号匹配

typ==2

技术图片
 1 #include<bits/stdc++.h>
 2 #define int long long
 3 #define R register
 4 using namespace std;
 5 const int mod=1e9+7;
 6 const int maxn=200005;
 7 int n,typ;
 8 int f[2][2005][2005];
 9 int fac[maxn],inv[maxn],facinv[maxn];
10 void init()
11 {
12     fac[0]=fac[1]=inv[0]=inv[1]=facinv[0]=facinv[1]=1;
13     for(R int i=2;i<=2*n+1;i++)
14     {
15         fac[i]=fac[i-1]*i%mod;
16         inv[i]=(mod-mod/i)*inv[mod%i]%mod;
17         facinv[i]=facinv[i-1]*inv[i]%mod;
18     }
19 }
20 int C(R int n,R int m)
21 {
22     return fac[n]*facinv[m]%mod*facinv[n-m]%mod;
23 }
24 int cat(R int n)
25 {
26     return C(2*n,n)*inv[n+1]%mod;
27 }
28 signed main()
29 {
30     scanf("%lld%lld",&n,&typ);
31     if(typ==2)
32     {
33         R int m=n<<1;
34         f[0][n][n]=1;
35         int t=0;
36         for(R int k=1;k<=n;++k)
37         {
38             t^=1;
39             for(R int i=0;i<=m;++i)
40                 f[t][i][n]=f[t][n][i]=0;
41             for(R int i=1;i<=m;++i)
42                 f[t][i][n]=(f[t][i][n]+f[t^1][i+1][n]+f[t^1][i-1][n])%mod;
43             for(R int j=1;j<=m;++j)
44                 f[t][n][j]=(f[t][n][j]+f[t^1][n][j+1]+f[t^1][n][j-1])%mod;
45             
46         }
47         printf("%lld\n",f[t][n][n]%mod);
48         return 0;
49     }
50 
51     R int ans=0;
52     init();
53     if(typ==0)
54         for(R int i=0;i<=n;i+=2)
55             ans=(ans+C(n,i)*C(i,i>>1)%mod*C(n-i,(n-i)>>1)%mod)%mod;
56     if(typ==1)
57         ans=cat(n>>1);
58     if(typ==3)
59         for(R int i=0;i<=n;i+=2)
60             ans=(ans+C(n,i)*cat(i>>1)%mod*cat((n-i)>>1)%mod)%mod;
61     printf("%lld\n",ans);
62 }
View Code

 

模拟9题解

标签:pow   view   复杂度   模拟   main   style   ace   src   c++   

原文地址:https://www.cnblogs.com/casun547/p/11261789.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!