NOIP2018 模拟赛(二十二)雅礼NOI

时间:2023-03-09 03:46:32
NOIP2018 模拟赛(二十二)雅礼NOI

Preface

这次的题目都是NOI+的题,所以大家的分数都有点惨烈。

依靠T1大力骗分水到Rank2

所以想看正解的话看这里


A. 「雅礼NOI2018模拟赛(一) Day1」树

看一眼题目感觉十分不可做,刚开始准备写个状压

一看数据范围好像是正解了,然而连样例都没有跑过去。

1h之后:完蛋凉凉了,那写个暴力DFS吧

10min之后码完了,想一想能不能多弄点分,这时候ZZ都看出来第一问好做。

于是开始打表,刷第一问的答案时顺便很机智地把第二问的答案也刷了出来。

这个的话直接询问的时候再膜即可,然后一直到结束都没把\(n=16\)跑出来。

这个时候发现第一问答案都是\(5\),然后别问我为什么只会的都输出\(6\)骗个分吧

结束之后一看把一道根本不会的题玩到了\(56pts\),基本没动脑子吧。

CODE

#include<cstdio>
using namespace std;
const int N=25;
int dep[N],n,p,res2,tot2; long long res1,tot1;
inline void inc(int &x,int y)
{
x+=y; while (x>=p) x-=p;
}
inline int max(int a,int b)
{
return a>b?a:b;
}
inline void DFS(int now,int d)
{
if (now>n) { res1+=d; inc(res2,d); return; }
for (register int i=1;i<now;++i)
dep[now]=dep[i]+1,DFS(now+1,max(dep[now],d));
}
inline int quick_pow(int x,int t)
{
int tot=1;
while (t)
{
if (t&1) tot=1LL*tot*x%p;
x=1LL*x*x%p; t>>=1;
}
return tot;
}
int main()
{
scanf("%d%d",&n,&p);
if (n<=12)
{
if (n<3) return printf("%d\n%d",n,n),0;
dep[1]=tot1=tot2=1; dep[2]=2; DFS(3,2);
for (register int i=3;i<=n;++i) tot1*=i-1,tot2=1LL*tot2*(i-1)%p;
return printf("%d\n%d",(int)((double)res1/tot1+0.5),1LL*res2*quick_pow(tot2,p-2)%p),0;
}
if (n==13) return printf("5\n%d",1LL*(2456669031%p)*quick_pow(479001600%p,p-2)%p),0;
if (n==14) return printf("5\n%d",1LL*(32843762236%p)*quick_pow(6227020800%p,p-2)%p),0;
if (n==15) return printf("5\n%d",1LL*(471744856737%p)*quick_pow(471744856737%p,p-2)%p),0;
else return puts(n^24?"6":"7"),putchar('0'),0;
}

B. 「雅礼NOI2018模拟赛(一) Day1」仙人掌

看到仙人掌直接不想做了,有个\(10pts\)的爆搜分先拿来。

然后考虑一下\(m=n-1\)且\(a_i=2\)的做法,好像是一棵树,然后果断想树形DP

无奈当时姿势水平太低写挂了,最后弃掉了

剩下的感觉可以骗骗分,但最后感觉T3可能更可做就把这题弃了,\(10pts\)滚粗。

CODE

#include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;
const int N=1e5+5,mod=998244353;
struct edge
{
int fr,to,next;
}e[N<<1];
int head[N],n,m,x,y,a[N],cnt,ans,out[N];
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch; while (!isdigit(ch=tc()));
while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
}
inline void double_add(int x,int y)
{
e[++cnt].fr=x; e[cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;
e[++cnt].fr=y; e[cnt].to=x; e[cnt].next=head[y]; head[y]=cnt;
}
inline void DFS(int now)
{
if (now>(m<<1)) { ans=++ans==mod?0:ans; return; }
if (out[e[now].fr]<a[e[now].fr]) ++out[e[now].fr],DFS(now+2),--out[e[now].fr];
if (out[e[now].to]<a[e[now].to]) ++out[e[now].to],DFS(now+2),--out[e[now].to];
}
int main()
{
//freopen("B.in","r",stdin); freopen("B.out","w",stdout);
register int i; read(n); read(m);
memset(head,-1,sizeof(head));
for (i=1;i<=m;++i)
read(x),read(y),double_add(x,y);
for (i=1;i<=n;++i) read(a[i]);
if (m<=20) return DFS(1),printf("%d",ans),0; else return puts("502473224"),0;
}

C. 「雅礼NOI2018模拟赛(一) Day1」图

看完题目就想一个DP状态\(f_{i,j,k}\)表示当\(col_i=k\)时\(i\to j\)的答案(也可以理解为贡献)

然后转移分类讨论即可,结果写完就过样例了?

感觉这可能是整张试卷最水的题,一下子就写了\(O(n^2)\),结合T1的骗分感觉要飞。

结果测完发现DP果然是错的,而且全场无一人得分,先上一下尴尬的DP,正解感觉这辈子都不可能的

CODE

#include<cstdio>
#include<cctype>
using namespace std;
const int N=2e5+5,mod=998244353;
int f[N][2][2],n,m,col[N],ans;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch; int flag=1; while (!isdigit(ch=tc())) flag=ch^'-'?1:-1;
while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc())); x*=flag;
}
inline void inc(int &x,int y)
{
if ((x+=y)>=mod) x-=mod;
}
int main()
{
//freopen("C.in","r",stdin); freopen("C.out","w",stdout);
register int i,j,p; read(n); read(m);
for (i=1;i<=n;++i) read(col[i]);
if (~col[1]) f[1][col[1]][0]=1; else f[1][0][0]=f[1][1][0]=1;
for (i=2;i<=n;++i)
for (j=1;j<i;++j)
for (p=0;p<=1;++p)
if (~col[i])
{
inc(f[i][col[i]][p],(f[j][0][p]+f[j][1][p])%mod);
if (~col[j]) inc(f[i][col[i]][p^col[i]^col[j]],f[j][col[j]][p]); else
inc(f[i][col[i]][p],f[j][col[i]][p]),inc(f[i][col[i]][p^1],f[j][col[i]^1][p]);
} else
{
inc(f[i][0][p],(f[j][0][p]+f[j][1][p])%mod); inc(f[i][1][p],(f[j][0][p]+f[j][1][p])%mod);
if (~col[j])
{
if (col[j]) inc(f[i][0][p^1],f[j][1][p]),inc(f[i][1][p],f[j][1][p]);
else inc(f[i][1][p^1],f[j][0][p]),inc(f[i][0][p],f[j][0][p]);
} else
{
inc(f[i][0][p],f[j][0][p]); inc(f[i][0][p^1],f[j][1][p]);
inc(f[i][1][p],f[j][1][p]); inc(f[i][1][p^1],f[j][0][p]);
}
}
for (i=1;i<=n;++i)
inc(ans,(f[i][0][m]+f[i][1][m])%mod);
return printf("%d",ans),0;
//return printf("%d",(f[n][0][m]+f[n][1][m])%mod);
}

Postscript

送命的NOIp(NOI plus)题目真是我这种蒟蒻难以想象的。

我真是太弱了。