T1 小L的疑惑

解题思路

第一眼不是正解,又是 bitset 优化可以得到的 60pts 的部分分。

打着打着突然发现这个东西好像和之前做过的某个题有一些相似,试着打了一下。

然后样例过了,然后对拍没错,然后就切了??

先排序,如果某个数之前所有数的和都比这个数字-1 小,那么这里就是一个空缺,扫的时候选择最小的空缺就是答案。

code

#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1e5+10,M=1e7+10,INF=1e18;
int n,cnt,s[N];
signed main()
{
freopen("math.in","r",stdin); freopen("math.out","w",stdout);
n=read(); for(int i=1;i<=n;i++) s[i]=read(); sort(s+1,s+n+1);
for(int i=1;i<=n;i++)
{
if(cnt<s[i]-1) printf("%lld",cnt+1),exit(0);
cnt+=s[i];
}
printf("%lld",cnt+1);
return 0;
}

T2 小L的数列

解题思路

发现运算都是乘法,于是我们考虑转化成为指数上的加法。

然后我们又看了一下 k 的范围,大概是矩阵乘法没错了,于是很好出来下移的做法复杂度大概是 \(k^3log(n-k)\)

但是我考场上一时糊涂竟然没有想到,于是整到了一个 \(k^3log\frac{n-k}{k}\) 的做法,也就是一次性转移 k 个。

单位矩阵的第一行就是 \(b_k,b_{k-1},...b_2,b_1\) 第二行其实就是 \(0,b_{k},...b_3,b_2\) 再加上第一行的系数每一项乘上一个 \(b_1\) 其它的系数也是类似。

然后我们就可以一次性转移 k 个了,免去了卡常的麻烦。

code

#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=4e7+10,M=210,mod=998244353;
int n,m,Ans=1,f[M],b[M];
struct Square
{
int a[M][M];
void clear(){memset(a,0,sizeof(a));}
Square friend operator * (Square x,Square y)
{
Square z; z.clear();
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
for(int k=1;k<=m;k++)
z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j])%(mod-1);
return z;
}
}e,ans;
void pw(Square &x,int y)
{
while(y)
{
if(y&1) x=x*e;
e=e*e; y>>=1;
}
}
int power(int x,int y,int p=mod)
{
int temp=1;
while(y)
{
if(y&1) temp=temp*x%mod;
x=x*x%mod; y>>=1;
}
return temp;
}
signed main()
{
freopen("seq.in","r",stdin); freopen("seq.out","w",stdout);
n=read(); m=read();
for(int i=1;i<=m;i++) b[i]=read();
for(int i=1;i<=m;i++) f[i]=read();
for(int i=1;i<=m;i++) ans.a[i][i]=1;
for(int i=1;i<=m;i++)
{
for(int j=i;j<=m;j++) e.a[i][j]=b[m-(j-i)];
for(int j=1;j<i;j++)
for(int k=1;k<=m;k++)
e.a[i][k]=(e.a[i][k]+e.a[j][k]*b[i-j])%(mod-1);
}
pw(ans,n/m+(n%m!=0)-1);
int pos=n%m; if(!pos) pos=m;
for(int i=1;i<=m;i++)
Ans=Ans*power(f[i],ans.a[pos][i])%mod;
printf("%lld",Ans);
return 0;
}

T3 连边

解题思路

尽管实际得分远高于期望得分,但是还是挂了 20pts 没有场上切掉(感觉不稳就判了一下暴力,然后暴力被卡常了。。)

大概就是一个多源最短路同时记录一下前驱,对于只有一个前驱的直接选择,对于多个前驱的选择权值最小的。。

本来我只是想对于随机数据下手的,想随便 rand() 一下,但是感觉不稳,就贪了个心,然后歪打正着??(算是吧。。)

code

#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=2e5+10,M=N<<1,INF=1e18;
int n,m,ans=INF,dis[N],fa[N];
int tot=1,head[N],nxt[M<<1],ver[M<<1],edge[M<<1];
bool col[N],vis[N],can[M];
struct Road{int l,r,val;}pat[M];
priority_queue<pair<int,int> > q;
vector<pair<int,int> > pre[N];
void add_edge(int x,int y,int val)
{
ver[++tot]=y; edge[tot]=val;
nxt[tot]=head[x]; head[x]=tot;
}
int find(int x)
{
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
signed main()
{
freopen("minimum.in","r",stdin); freopen("minimum.out","w",stdout);
n=read(); m=read();
for(int i=1;i<=n;i++) vis[i]=col[i]=read(),fa[i]=i;
for(int i=1,x,y,val;i<=m;i++)
{
x=read(); y=read(); val=read(); pat[i]=(Road){x,y,val},
add_edge(x,y,val); add_edge(y,x,val);
if(find(x)==find(y)) continue;
vis[find(y)]|=vis[find(x)];
fa[find(x)]=find(y);
}
for(int i=1;i<=n;i++) if(!vis[find(i)]) printf("impossible"),exit(0);
memset(dis,0x3f,sizeof(dis)); memset(vis,false,sizeof(vis));
for(int i=1;i<=n;i++) if(col[i]) dis[i]=0,q.push(make_pair(0,i));
while(!q.empty())
{
int x=q.top().second; q.pop();
if(vis[x]) continue; vis[x]=true;
for(int i=head[x];i;i=nxt[i])
{
int to=ver[i],val=edge[i];
if(dis[to]<dis[x]+val) continue;
if(dis[to]>dis[x]+val) vector<pair<int,int> >().swap(pre[to]);
dis[to]=dis[x]+val; pre[to].push_back(make_pair(x,i));
if(!vis[to]) q.push(make_pair(-dis[to],to));
}
}
for(int i=1;i<=n;i++) if(pre[i].size()==1) can[pre[i][0].second>>1]=true;
for(int i=1;i<=n;i++)
if(pre[i].size()!=1)
{
int minn=INF,id=0;
for(int j=0;j<pre[i].size();j++) if(can[pre[i][j].second>>1]) goto X;
for(int j=0;j<pre[i].size();j++) if(minn>edge[pre[i][j].second]) id=pre[i][j].second,minn=edge[id],id>>=1;
can[id]=true; X:;
}
ans=0;
for(int i=1;i<=m;i++) ans+=can[i]*pat[i].val;
printf("%lld",ans);
return 0;
}

T4 小L的有向图

解题思路

看到 T4 的时候只有 30min 了,感觉不是特别好搞,我直接 printf("0") 然后去看前面的了。。

考完之后听了一下正解思路感觉神似竞赛图,但又不完全是。

\(f_{S}\) 表示 \(S\) 点集内部合法拓扑序的个数然后枚举集合外面的点,计算集合内点到对应点的连边数量作为 2 的指数就是这个点的贡献。

code

#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=25,mod=998244353;
int n,m,e[N],f[1<<22],sum[1<<22];
int lowbit(int x){return x&(-x);}
signed main()
{
freopen("topology.in","r",stdin); freopen("topology.out","w",stdout);
n=read(); m=read();
for(int i=1,x,y;i<=m;i++) x=read(),y=read(),e[y]|=1<<x-1;
for(int i=1;i<=n;i++) sum[1<<i-1]=1; f[0]=1;
for(int i=1;i<(1<<n);i++)sum[i]=sum[i^lowbit(i)]+sum[lowbit(i)];
for(int sta=0;sta<(1<<n);sta++)
for(int i=1;i<=n;i++)
{
if((sta>>i-1)&1) continue;
int temp=sum[sta&e[i]];
f[sta|(1<<i-1)]=(f[sta|(1<<i-1)]+f[sta]*(1ll<<temp))%mod;
}
printf("%lld",f[(1<<n)-1]);
return 0;
}

T? 中国象棋

解题思路

由于今天的考试题目比较简单,教练就又加了几道题,看了看好像就这道比较好做,大致口胡一下。

显然每行每列最多只可能有两个棋子,于是设 \(f_{i,j,k}\) 表示前 i 行,有 j 列只有一个棋子,有 k 列只有两个棋子。

然后分别枚举不放旗子,在有一个棋子的列放一个,在没有的放一个或者两个,在没有的有一个的各放一个,在有一个的放两列。

code

#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=110,mod=9999973;
int n,m,ans,f[N][N][N];
void add(int &x,int y){x+=y;if(x>=mod)x-=mod;}
int C2(int x){return x*(x-1)/2;}
void solve(int i,int j,int k)
{
if(!f[i][j][k]) return ;
add(f[i+1][j][k],f[i][j][k]);
add(f[i+1][j+1][k],f[i][j][k]*(m-j-k)%mod);
add(f[i+1][j+2][k],f[i][j][k]*C2(m-j-k)%mod);
if(j>=2) add(f[i+1][j-2][k+2],f[i][j][k]*C2(j)%mod);
if(j>=1) add(f[i+1][j-1][k+1],f[i][j][k]*j%mod),add(f[i+1][j][k+1],f[i][j][k]*(m-j-k)%mod*j%mod);
}
signed main()
{
freopen("chess.in","r",stdin); freopen("chess.out","w",stdout);
n=read(); m=read(); f[0][0][0]=1;
for(int i=0;i<n;i++) for(int j=0;j<=m;j++) for(int k=0;k<=m-j;k++) solve(i,j,k);
for(int i=0;i<=m;i++) for(int j=0;j<=m-i;j++) add(ans,f[n][i][j]);
printf("%lld",ans); return 0;
}

NOIP模拟73的更多相关文章

  1. Noip模拟73 2021.10.10

    老妈送来了防寒补给就很棒,再也不用晚上盖两层毛巾被了,再也不用担心晚上自动把毛巾被$split$了 还有一些好吃的耶叶 T1 小L的疑惑 考场上疑惑的切掉了 直接把$a$排序然后处理前缀和的过程中判断 ...

  2. 2021.10.10考试总结[NOIP模拟73]

    T1 小L的疑惑 对于\(P_i\),如果所有比\(P_i\)小的数加起来也达不到\(P_i-1\),那么值域肯定不连续.否则设原来值域最大值为\(mx\),则\(P_i\)会让值域最大值增致\(mx ...

  3. NOIP模拟17.9.22

    NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥

  4. NOIP 模拟4 T2

    本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...

  5. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  6. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  7. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  8. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  9. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

随机推荐

  1. 深入研究webpack之Tree Shaking相关属性sideEffects用处

    Tree Shaking我原来也只是了解,这次碰巧深入研究了下,就写个博客记录一下,网上有很多讲Tree Shaking的,我写的这篇跟他们侧重点不一样 Tree Shaking相关的基础知识 1 w ...

  2. python pip/anaconda使用笔记

    Switch to Chinese conda Source, config file is in ~/.condarc conda config --add channels https://mir ...

  3. MySQL锁(表锁,行锁,共享锁,排它锁,间隙锁)使用详解

    锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是协调多个进程或县城并发访问某一资源的一种机制.在数据库当中,除了传统的计算资源(CPU.RAM.I/O等等)的争用之外,数据也是一 ...

  4. JQ动画

    /* //基本 show([s,[e],[fn]]) 显示元素 hide([s,[e],[fn]]) 隐藏元素 //滑动 slideDown([s],[e],[fn]) 向下滑动 slideUp([s ...

  5. noip模拟测试50

    考试过程:开题顺序1,2,3,做T1的时候我想到了要求的东西,就是分成尽量少的段使得每段之和>=k,但是我不会求,就打了个暴力走了,然后看T2,这题我觉得和之前做过的一道题比较像,因为我觉得\( ...

  6. Object.keys( )与 for in 区别

    for in 一般用于对象的遍历: let obj = { a:1, b:2, } for(let key in obj){ console.log(key) } // a // b Object.k ...

  7. tar解压缩问题

    gzip: stdin: unexpected end of filetar: 归档文件中异常的 EOFtar: 归档文件中异常的 EOFtar: Error is not recoverable: ...

  8. 关于软链接ln -s 的使用

    1.效果跟windows创建快捷方式是一样的,先找到要被创建的原始文件或目录.然后才能创建. 2.格式:ln  -s   [源文件或目录]   [目标文件或目录] 3.源文件或目录必须是绝对目录. 4 ...

  9. Centos 6.8 系统下安装RabbitMQ方法

    一,安装 RabbitMQ 首先要先安装 erlang 1,到erlang官网下载 OTP 19.0 Source File 2,解压 tar zvxf otp_src_19.0.tar.gz 3,c ...

  10. use关键字在PHP中的几种用法

    在学习了和使用了这么多年的PHP之后,您知道use这个关键字在PHP中都有哪些用法吗?今天我们就来看一下它的三种常见用法. 1. 用于命名空间的别名引用 // 命名空间 include 'namesp ...