模拟赛题解锦集——Hzoi

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟赛题解锦集——Hzoi相关的知识,希望对你有一定的参考价值。

 

Day IXV:

  题目链接

  T1:

   对于二者之一$n$,每次选取要么变成$2n$,要么是$n-(tot-n)=2*n-tot$,即最后结果为$n*2^{k}(\mod tot)$.

  T2:

   思博题。枚举每个右边界$pos$,求其左边界$l[pos]$,显然其左边界应该是$l[pos-1]$和最后一个满足$a_{x}-K$为$a_{pos}$的倍数之间取一个较大值,然后用该数更新一下边界位置即可。

  T3:

   其实DP是蛮裸的,可惜第一题浪费时间太久,最后半个小时想法已经很接近答案,但是也没怎么细想,这是今天最大的失误。

    设$f_{i,j}$表示前$i$层已经选好且第$i$层恰好选取了$j$种颜色的全部方案,再设两个辅助数组$g_{i,j},gc_{i,j}$。其中$g_{i,j}$表示长度为i的装饰品,只使用确定的j种颜色的方案数,$gc$则表示任意j种颜色的方案数。

   然后我们很容易得到一个递推式:$f_{i,j}=gc_{i,j}\sum_{x=1}^{a[i-1]}f_{i-1,x}-g_{i,j}f_{i-1,j}$。

   再考虑如何得到$g$和$gc$数组。考虑组合意义:$g_{i,j}=g_{i-1,j}(j-1)+g_{i-1,j-1}j$,$gc_{i,j}=g_{i,j}*(_{j}^{m})$。但是此题模数不保证为质数,所以组合数不好处理,换一种思路$gc_{i,j}=gc_{i-1,j}(j-1)+gc_{i-1,j-1}(m-j+1)$。

   然后就可以$O(max(a_{i})^2+S)$解决问题了。

代码:

T1:

1 #include <cstdio>
2 int n,m,k,x=2;
3 int main(){
4     scanf("%d%d%d",&n,&m,&k),m=n+m;
5     for(;k;(k&1)?n=1ll*n*x%m:0,k>>=1,x=1ll*x*x%m);
6      printf("%d",n<m-n?n:m-n);
7 }

T2:

 1 #define Troy 10/14/2017
 2  
 3 #include <bits/stdc++.h>
 4  
 5 using namespace std;
 6  
 7 inline int read(){
 8     int s=0,k=1;char ch=getchar();
 9     while(ch<0||ch>9)   k=ch==-?-k:k,ch=getchar();
10     while(ch>47&&ch<=9)   s=s*10+(ch^48),ch=getchar();
11     return s*k;
12 }
13  
14 typedef long long ll;
15  
16 const int N=1e5+7;
17  
18 int n,k,a[N],l[N],r[N];
19 int last[N];
20  
21 inline void add(int x,int pos){
22     if(x<0) return ;
23     if(x==0){    
24         last[x]=pos;
25         return ;
26     }
27     for(int i=1;1ll*i*i<=x;i++){
28         if(x%i==0)
29             last[i]=pos,last[x/i]=pos;
30     }
31 }
32  
33 int main(){
34     n=read(),k=read();
35     for(int i=1;i<=n;i++)
36         a[i]=read();
37     l[0]=1;
38     for(int i=1;i<=n;i++){
39         if(a[i]>k)
40             l[i]=max(max(last[a[i]],last[0])+1,l[i-1]);
41         else
42             l[i]=l[i-1];
43         add(a[i]-k,i);
44     }
45     ll ans=0;
46     for(int i=1;i<=n;i++)
47         ans=ans+(i-l[i]+1);
48     printf("%lld\n",ans);
49 }

T3:

 1 #define Troy 10/14/2017
 2 
 3 #include <cstdio>
 4 #include <vector>
 5 
 6 using namespace std;
 7 
 8 inline int read(){
 9     int s=0,k=1;char ch=getchar();
10     while(ch<0||ch>9)   k=ch==-?-k:k,ch=getchar();
11     while(ch>47&&ch<=9)   s=s*10+(ch^48),ch=getchar();
12     return s*k;
13 }
14 
15 typedef long long ll;
16 
17 const int N=5e3+7;
18 
19 int n,m,p,a[(int)1e6+7],f[2][N],gc[N][N],g[N][N];
20 
21 int main(){
22     n=read(),m=read(),p=read();
23     for(int i=1;i<=n;i++)
24         a[i]=read();
25     g[0][0]=1;
26     gc[0][0]=1;
27     for(int i=1;i<=5000;i++){     
28         for(int j=1;j<=min(i,m);j++){
29             g[i][j]=(1ll*g[i-1][j]*(j-1)+1ll*g[i-1][j-1]*j)%p,
30             gc[i][j]=(1ll*gc[i-1][j]*(j-1)%p+1ll*gc[i-1][j-1]*(m-j+1)%p)%p;
31         }    
32     }
33     f[0][0]=1;
34     int now=1,last=0;
35     for(int i=1;i<=n;i++){
36         for(int j=1;j<=a[i];j++){
37             f[now][j]=1ll*f[last][0]*gc[a[i]][j]%p;                        
38             if(a[i-1]>=j)
39                 f[now][j]-=1ll*f[last][j]*g[a[i]][j]%p;
40             f[now][j]=(f[now][j]%p+p)%p;            
41 
42             f[now][0]=(f[now][0]+f[now][j])%p;            
43             f[last][j]=0;
44         }
45         f[last][0]=0,now^=1,last^=1;
46     }
47     printf("%d\n",f[last][0]);
48 }
49 /*
50 3 2 1000
51 3 1 2
52 */

 

以上是关于模拟赛题解锦集——Hzoi的主要内容,如果未能解决你的问题,请参考以下文章

HZOI20190908模拟40 队长快跑,影魔,抛硬币 题解

COGS 2188. [HZOI 2015] Math 题解

cogs 2320. [HZOI 2015]聪聪的世界题解

CSP-S 模拟测试57题解

HZOI2019 A. 那一天我们许下约定 dp

HZOI2019序列