10-30 NOIP模拟赛

今天分数还看的过去,只是第二题没有正解,第三题没有35我表示很伤心。必须继续努力,保持内心纯净,心无杂念,知行合一,摒除恶念。

100 + 80 + 5 = 185 芜湖!

T1 新的阶乘(factorial)

题目描述

我们定义 \(f(x)=x^1×(x−1)^2×(x−2)^3…2^{x−1}×1^x\),请求出 \(f(n)\) 的质因子分解形式。

输入数据 1

5

输出数据 1

f(5)=2^8*3^3*5

首先观察数据范围 \(2≤n≤10^7\),首先就想到 \(O(n)\) 的做法,这道题唯一需要我们做的就是把合数分解成其的质因数,我们考虑遇到一个合数怎么办,如果把它分解成质因数肯定是不怎么优的,实际上这么做也确实只有30分,只能过 \(10^5\)。

其实接下来就很轻松想到,其实只要把每个数分解成两个数相乘即可,这样从大枚举到小,就能把所有的数全部都给分解掉。怎么把每个数拆成两个数呢,试除肯定是不现实的,质数需要枚举的 \(\sqrt n\),就用线性筛即可,不是质数的数,开一个数组记录其最小质因子。

代码也很好懂的啦!

#include<bits/stdc++.h>
using namespace std;
#define N 12000010
int prime[N],cnt=0;
int n,sp[N];
long long m[N];
bool isp[N]; void primes(int x){
memset(isp,1,sizeof(isp));
for(int i=2;i<=x;i++){
if(isp[i]) prime[++cnt]=i;
for(int j=1;j<=cnt;j++){
if(i*prime[j]>x) break;
isp[i*prime[j]]=0;sp[i*prime[j]]=prime[j];
if(i%prime[j]==0) break;
}
}
} int main(){
freopen("factorial.in","r",stdin);
freopen("factorial.out","w",stdout);
scanf("%d",&n);
primes(n);
for(int i=n;i>=2;i--){
long long num=n-i+1;
if(isp[i]) m[i]+=num;
else{
m[sp[i]]+=num+m[i];
m[i/sp[i]]+=num+m[i];
m[i]=0;
}
}
printf("f(%d)=",n);
int s=2;
while(!m[s]) s++;
printf("%d",s);
if(m[s]>1) printf("^%lld",m[s]);
for(int i=s+1;i<=n;i++){
if(m[i]){
printf("*%d",i);
if(m[i]>1) printf("^%lld",m[i]);
}
}
return 0;
}

T2 博弈树(tree)

题目描述

Alice 和 Bob 又开始玩游戏了, 他们已经把石子堆得比山还高了, 现在他们要玩一种更新奇的游戏,这种游戏的规则如下:

  • 给定一颗 \(n\) 个节点的树,Alice 和 Bob 随机选择一个节点作为起点放上棋子,由 Alice 先手。
  • 轮到一方后可以将这颗棋子移动到树上任意一点,每次一方移动的距离必须比对方上一次移动的距离还要大,开始时默认为 0 。
  • 当一方不能再次移动之后判负。

现在 Alice 和 Bob 已经找到了一棵节点编号为 \(1∼n\) 的树准备开始游戏,作为博亦高手,Alice 和 Bob 均会做出最优的选择,选择一个节点后,他们知道游戏必然有一种必胜策略,现在他们想知道游戏的胜负,他们会询问你 \(q\) 次,每次他们会选择一个节点询问,你只需要回答在最优策略下以这个为节点为起点的胜者是谁即可。

输入数据 1

6 3
1 2
2 3
2 4
1 5
4 6
2
3
1

输出数据 1

Bob
Alice
Alice

这是很少遇到的比较有意思的 T2,只不过呢,就是正解有点太简单了。

你告诉我直接输出 Alice 有70分?????(好歹来个捆绑啊

先讲暴力 80 分做法:

受到昨天坐的 NOIP2021 T2 的暴力启发,我打了一个记忆化爆搜,即 \(f_{i,j}\) 表示当前在编号为 \(i\) 的节点上,上一步走的距离为 \(j\),然后每次询问暴力枚举当前点能走到的所有点,如果有一个点必输,那么当前点必赢,如果全部都必赢,那么当前点必败。

80 分代码:

#include<bits/stdc++.h>
using namespace std;
#define N 300005
int fir[N],nex[N],to[N],tot=0;
int n,q;
int f[5010][5010];
int dep[5010][5010]; void add(int x,int y){
nex[++tot]=fir[x];
fir[x]=tot;
to[tot]=y;
} void find(int x,int u,int fa){
dep[x][u]=dep[x][fa]+1;
for(int e=fir[u];e;e=nex[e]){
int v=to[e];
if(v==fa) continue;
find(x,v,u);
}
} int dfs(int u,int x){
if(f[u][x]) return f[u][x];
if(dep[u][u]!=-520){
dep[u][u]=-520;
dep[u][0]=-1;
find(u,u,0);
}
for(int i=1;i<=n;i++){
if(i==u) continue;
if(dep[u][i]>x){
if(dfs(i,dep[u][i])==2)
return f[u][x]=1;
}
}
return f[u][x]=2;
} int main(){
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
scanf("%d%d",&n,&q);
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
for(int i=1;i<=q;i++){
int u;
scanf("%d",&u);
if(!f[u][0]) dfs(u,0);
if(f[u][0]==2){
printf("Bob\n");
}
else{
printf("Alice\n");
}
}
return 0;
}

然后来思考正解:

我们考虑先手的位置如果在直径端点的话一定是先手必胜的,否则先手一定不能将点移动到直径端点,于是我们考虑删除了原树所有直径端点的树,如果初始点在这棵树上为直径端点那么也一定是先手必胜的,因为先手可以将点移动到另一个直径端点,这样后手就一定会将点移动到原树的直径端点上,并且移动的长度一定小于原树直径,这样先手就可以将点移动到原树的另一个直径端点取得胜利。

所以这样我们可以将树的叶子一层一层的删下去,如果最后删剩下一个点那么在这个点是后手必胜的(因为先手无论如何都会将这个点移动到某一层的直径端点),否则根据我们之前的证明先手一定可以通过不断将点移动到下一层的直径端点取得胜利。

直接实现是 \(O(n^2)\) 的,不过我们注意到原树的直径中点一定是删一层后树的直径中点,于是直接判断原树直径长度即可。

AC 代码:

#include <bits/stdc++.h>
using namespace std;
#define N 100010
int n,q;
vector<int>e[N];
int fa[N];
int p=1,dep[N],st,ed;
int bs;
void dfs(int u, int f){
dep[u]=dep[f]+1;
fa[u]=f;
if (dep[u]>dep[p]) p=u;
for (auto v:e[u]) {
if (v==f) continue;
dfs(v,u);
}
}
int main() {
freopen("tree.in", "r", stdin);
freopen("tree.out", "w", stdout);
scanf("%d%d",&n,&q);
for (int i=1,u,v;i<n;++i) {
scanf("%d%d",&u,&v);
e[u].emplace_back(v);
e[v].emplace_back(u);
}
dfs(1, 0);st=p;
dfs(p, 0);ed=p;
if(dep[ed] & 1){
bs=ed;
for (int i=0;i<dep[ed]/2;++i) bs=fa[bs];
}
for(int i=1,u;i<=q;++i) {
scanf("%d",&u);
puts(u == bs ? "Bob" : "Alice");
}
return 0;
}

T3 划分(divide)

题目描述

对于一个长度为 \(n\) 的 01 字符串 \(S\),请你求出将其分为至少 \(k\) 段,将每一段看为二进制数求和后的最大值以及取到这个最大值的划分方案的数量。

输入格式

输入的第一行包含两个正整数 \(n, k\),保证 \(n \leq 2 \times 10^{6}\);\(1 \leq k \leq n\) 。

输入的第二行包含一个长度为 \(n\) 的字符串 \(S\),保证 \(S\) 只包含字符 \(0,1\) 。

输出格式

输出一行两个整数,分别表示最大的和 \(\bmod \ 998244353\) 的值以及此时划分的方案数 \(\bmod\ 998244353\) 的值。

10-30 NOIP模拟赛的更多相关文章

  1. 2016.10.30 NOIP模拟赛 day2 PM 整理

    满分:300分 直接全部爆零,真的是很坑啊! 10.30的题目+数据:链接:http://pan.baidu.com/s/1jHXLace 密码:i784 T1: 题目中的难点就是每次折叠的点可能应经 ...

  2. 2016.10.30 NOIP模拟赛 day2 AM 整理

    题目+数据:链接:http://pan.baidu.com/s/1gfBg4h1 密码:ho7o 总共得了:130分, 1:100分  2:30分(只会这30分的暴力) 3:0(毫无思路) 虽然不高, ...

  3. 2018.10.30 NOIp模拟赛T2 数字对

    [题目描述] 小 H 是个善于思考的学生,现在她又在思考一个有关序列的问题.        她的面前浮现出一个长度为 n 的序列{ai},她想找出一段区间[L, R](1 <= L <= ...

  4. 2018.10.30 NOIp模拟赛 T1 改造二叉树

    [题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随后他又和他人讨论 ...

  5. 10.16 NOIP模拟赛

    目录 2018.10.16 NOIP模拟赛 A 购物shop B 期望exp(DP 期望 按位计算) C 魔法迷宫maze(状压 暴力) 考试代码 C 2018.10.16 NOIP模拟赛 时间:2h ...

  6. 10.17 NOIP模拟赛

    目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...

  7. 10.30 NFLS-NOIP模拟赛 解题报告

    总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没 ...

  8. 2018.10.16 NOIP模拟赛解题报告

    心路历程 预计得分:\(100 + 100 + 20 = 220\) 实际得分:\(100 + 100 + 30 = 230\) 辣鸡模拟赛.. T1T2都是一眼题,T3考验卡常数还只有一档暴力分. ...

  9. 2017 10.25 NOIP模拟赛

    期望得分:100+40+100=240 实际得分:50+40+20=110 T1 start取了min没有用,w(゚Д゚)w    O(≧口≦)O T3 代码3个bug :数组开小了,一个细节没注意, ...

  10. 2018.10.03 NOIP+ 模拟赛 解题报告

    得分: \(30+5+0=35\)(考得真不咋滴) \(T1\):奥义商店(点此看题面) 以为很简单,对着这题想了一个多小时,最后果断打了个暴力交了... ... 看完题解发现其实也不是很难. 对于\ ...

随机推荐

  1. scratch源码下载 | 超大太空游戏【80MB】

    按方向键或AWSD键控制角色移动,按空格键或X键攻击. 程序超级大,共80MB,耐心等待加载. 截图: 点击下载源码 更多源码访问:小虎鲸scratch资源站

  2. hbuilder打包的应用上架appstore屏幕快照的生成方法

    当我们使用hbuiderX或apicloud这些打包工具进行打包的时候,我们需要将打包好的ipa文件进行上架,但是你会发现,我们上架的时候需要上传5.5寸的iphone.6.5寸的iphone X和两 ...

  3. 对比python学julia(第一章)--(第二节)似曾相识燕归来

    Julia和python一样,都是跨平台开源语言,而且都是动态语言,所以毫无疑问,需要运行时支撑.很简单,到官网去下载julia(https://julialang.org/downloads/).和 ...

  4. 【Vue】06 Webpack Part2 打包命令配置

    Webpack 配置: 入口 & 出口: 就是我们使用的打包命令: 一个是对什么文件执行,这就是入口 一个是输出到什么文件,这就是出口 每一次打包使用这个命令都必须指定这两个必要的参数 所以将 ...

  5. 人形机器人 —— NVIDIA公司给出的操作算法(动态操作任务,dynamic manipulation tasks)(机械手臂/灵巧手)框架示意图 —— NVIDIA Isaac Manipulator

    原文: https://developer.nvidia.com/isaac/manipulator#foundation-models NVIDIA公司准备针对人形机器人的各部分操作分别推出一个AI ...

  6. tensorflow1.x——如何在C++多线程中调用同一个session会话

    相关内容: tensorflow1.x--如何在python多线程中调用同一个session会话 ================================================= 从 ...

  7. pytorch中使用vutils对多张图像进行拼接 (import torchvision.utils as vutils)

    1.png 2.png 在pytorch中使用torchvision的vutils函数实现对多张图片的拼接.具体操作就是将上面的两张图片,1.png和2.png的多张图片进行拼接形成一张图片,拼接后的 ...

  8. C# Cefsharp 设置代理方法

    前提条件 为了实现在cefsharp里面设置代理,首先在创建一个ChromiumWebBrowser的时候,检查是否使用了以下代码 settings.CefCommandLineArgs.Add(&q ...

  9. 如何查看mongodb的索引命中率

    如何查看mongodb的索引命中率 一.背景 现在mongodb使用率很高,经常会遇到查询慢时,就会创建索引,而有时候索引命中率又不高,下面来介绍下测试环境下如何查看索引命中率 二.方案 1.首先查看 ...

  10. 网卡DM9000裸机驱动详解

    一.网卡 1. 概念 网卡是一块被设计用来允许计算机在计算机网络上进行通讯的计算机硬件.由于其拥有MAC地址,因此属于OSI模型的第2层.它使得用户可以通过电缆或无线相互连接. 每一个网卡都有一个被称 ...