【2024.10.03】NOIP2024 赛前集训-刷题训练(5)

NOIP2017 提高组 小凯的疑惑

形式化题面:求最大的正整数 \(w\),满足 \(ax + by = w\) 不存在一对非负整数解。

第一眼想到 \(exgcd\),拿来分析一下:

因为 \(gcd(a,b) = 1\),所以 \(\forall w \in \mathbb{N^+}\) 肯定都有解,但不一定 \(x, y\) 都是非负整数。

接着容易发现,当其中一个未知数的解为 \(-1\) 时,\(w\) 可能就不满足条件。

但这个条件只是必要的。举个例子 :

\[3 \times 8 + 7 \times (-1) = 21 = 3 \times (8 - 7) + 7 \times(-1 + 3) = 3 \times 1 + 7 \times 2
\]

于是我们发现当 \(y = -1\) 时,\(w\) 满足题目条件当且仅当 $ x \lt b$。从 \(exgcd\) 的通解求法来讲,就是不能通过 \(x+kb, y -kb\) 来构造出一组非负整数解。

那么 \(w = a \times (b - 1) + b \times (-1) = a \times b - a - b\), 令 \(x = -1\) 推出来时一样的。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
using namespace std;
using ll = long long ;
ll a, b;
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> a >> b;
cout << a * b - a - b << '\n';
return 0;
}

NOIP2017 提高组 时间复杂度

小模拟。把细节列出来认真写就好,耐得住性子总能找到缺陷调出来。

注意一下对时间复杂度的统计是遇到 F 就+ 1并更新 mx,遇到 E 就- 1。

借助 \(STL\) 可以省很多事。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
using namespace std;
using ll = long long ;
int T;
int len, num, cnte, cntf, mx;
stack<pair<char, int>> stk;
map<char, int> mp;
char omiga[10000], type[10000], name[10000], x[10000], y[10000];
int change(char *a){
if(a[0] == 'n') return 100000000;
int val = 0;
for(int i = 0; a[i]; ++i) val = val * 10 + a[0] - 48;
return val;
}
int solve(){
int ans = 2;
cin >> len >> omiga;
bool flag = 0;
int answer = 0;
num = 0;
cnte = 0;
cntf = 0;
mx = 0;
char stop = ' ';
mp.clear();
while(stk.size()) stk.pop();
for(auto x:omiga){
if(x == 'n') flag = 1;
if(isdigit(x)){
if(!flag) answer = 0;
else answer = answer * 10 + x - 48;
}
}
F(i, 1, len){
cin >> type;
if(type[0] == 'E'){
if(ans == -1) continue;
++cnte;
if(cnte > cntf) {
ans = -1;
continue;
}
char nw = stk.top().first;
int delta = stk.top().second;
stk.pop();
if(stop == nw) stop = ' ';
if(!isalpha(stop) && delta > 100) -- num;
mp[nw] = 0;
}
else{
++cntf;
cin >> name >> x >> y;
if(ans == -1) continue;
if(mp[name[0]] != 0) ans = -1;
int delta = change(y) - change(x) + 1;
mp[name[0]] = 1;
stk.emplace(name[0], delta);
if(isalpha(stop)) continue;
if(delta > 100) mx = max(mx, ++num);
if(delta <= 0) stop = name[0];
}
}
if(ans == -1 || cnte != cntf) return -1;
if(answer == mx) return 1;
return 0;
}
signed main(){
// freopen("ex_complexity2.in","r",stdin);
// freopen("complexity.out","w",stdout);
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> T;
while(T -- ){
int ans = solve();
if(ans == 1) cout << "Yes\n";
else if(ans == 0) cout << "No\n";
else cout << "ERR\n";
}
return 0;
}

NOIP2017 提高组 逛公园

第一步,找零环(小trick:先只连权值为 0 的边跑 \(tarjan\))。

第二步,跑 \(dijkstra\)。

第三步,建反图记忆化搜索方案数。

我们记 \(f[i][j]\) 表示 \(1\) 到 \(i\) 的路径长为 \(dis[i] + j\) 的最短路,对于边 \((v, u, w)\), 因为 \(dis[v] + w + j[v] = dis[u] + j[u]\), 即 \(j[v] = dis[u] + j[u] - w - dis[v]\), 有如下转移:

\[f[u][j] += f[v][dis[u] + j - w - dis[v]]
\]

注意初始化写完整,两张图的相关数组不要混用!

!!!自己疏忽的地方:\(f[1][0] = 1\), 但 \(f[1][k] = 0\) 不一定成立,因为可以从某个点绕回 \(1\), 这样 \(f[1][k]\) 就是有贡献的了。

积累 dp 统计方案的这个方法。(类似分层图)

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
#define mk make_pair
#define fi first
#define se second
#define index iiiiidx
using namespace std;
using ll = long long ;
const int N = 2e5 + 5;
const ll inf = 0x3f3f3f3f3f3f3f3f;
struct cat{ int u, v, w; }edge[N << 1];
struct node{ int v, w, ne; }e[N << 2], g[N << 2]; ll dis[N], f[N][105];
bool vis[N];
priority_queue<pair<ll, int> >q; int first[N], idx = 0;
int head[N], index = 0; int dfn[N], low[N], scc[N], cnt = 0, num = 0;
bool ins[N];
stack<int> stk; int T, n, m, k, mod; void add(int x, int y, int z){ e[++idx] = (node){y, z, first[x]}; first[x] = idx; }
void ADD(int x, int y, int z){ g[++index] = (node){y, z, head[x]}; head[x] = index; }
void tarjan(int u, int f){
dfn[u] = low[u] = ++cnt, stk.emplace(u), ins[u] = 1;
for(int i = first[u];i ;i = e[i].ne){
int v = e[i].v;
if(!dfn[v]) tarjan(v, u),low[u] = min(low[u], low[v]);
else if(ins[v]) low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u]){
++num; int x, siz = 0;
do{ x = stk.top();
ins[x] = 0;
scc[x] = num;
stk.pop();
++siz;
}while(x != u);
if(siz == 1) scc[x] = 0, --num;
}
}
void dijkstra(int st){
while(q.size()) q.pop();
q.emplace(mk(0, st));
dis[st] = 0;
while(q.size()){
int u = q.top().se; q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(int i = first[u]; i; i = e[i].ne){
int v = e[i].v, w = e[i].w;
if(dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
q.emplace(mk(-dis[v], v));
}
}
}
}
ll dfs(int u, int k){
if(scc[u]) return -1;
if(u == 1 && k == 0) return f[u][k] = 1;
if(f[u][k] != -1) return f[u][k];
ll ret = 0;
for(int i = head[u]; i; i = g[i].ne){
int v = g[i].v, w = g[i].w;
ll tmp = dis[u] + k - w - dis[v];
if(tmp >= 0 && tmp <= k) {
int delta = dfs(v, tmp);
if(delta == -1) return -1;
(ret += delta) %= mod;
}
}return f[u][k] = ret;
}
void init(){
memset(dis, 0x3f, sizeof(dis));
memset(f, -1, sizeof(f));
memset(vis, 0, sizeof(vis));
memset(first, 0, sizeof(first)); idx = 0;
memset(head, 0, sizeof(head)); index = 0;
memset(dfn, 0, sizeof(dfn)); cnt = 0; num = 0;
memset(low, 0, sizeof(low));
memset(scc, 0, sizeof(scc));
memset(ins, 0, sizeof(ins));
if(stk.size()) stk.pop();
cin >> n >> m >> k >> mod;
F(i, 1, m){
int u, v, w;
cin >> u >> v >> w;
edge[i] = (cat){u, v, w};
if(w == 0) add(u, v, w), ADD(v, u, w);
}
F(i, 1, n) if(!dfn[i]) tarjan(i, 0);
}
int solve(){
F(i, 1, m){
int u = edge[i].u, v = edge[i].v, w = edge[i].w;
if(w != 0) add(u, v, w), ADD(v, u, w);
}
dijkstra(1);
ll ans = 0;
F(i, 0, k) {
ll delta = dfs(n, i);
if(delta == -1) return -1;
(ans += delta) %= mod;
}
return ans;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> T;
while(T--){
init();
cout << solve() << '\n';
}
return 0;
}

NOIP2017 提高组 奶酪

前置知识:球之间位置关系的判定依据:圆心距 与 半径和的关系。

下文用 “相切” 代指 “相切或相交”

算法1:并查集维护球之间的关系,\(O(Tn^2)\)。

算法2:先按 \(z\) 从小到大对所有圆心 \(a[i]\) 排序。另开一个数组 \(b\),若当前 \(a[i]\) 与 某个 \(b[j]\) 相切或者与下表面相切,就放进 \(b\) 里面。最后只需要判断是否存在 \(b[i]\) 与上表面相切就行。时间严格弱于 \(O(Tn^2)\)。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
#define int ll
using namespace std;
using ll = long long ;
const int N = 1005;
int T;
int n, h, r, btop = 0;
__int128 base;
__int128 pw(__int128 x){
return x * x;
}
struct node{
int x, y, z;
bool operator < (const node &o)const{
return z < o.z;
}
__int128 operator - (const node &o)const{
return pw(x - o.x) + pw(y - o.y) + pw(z - o.z);
}
}a[N], b[N];
inline bool check(int nw){
if(a[nw].z <= r) return 1;
F(i, 1, btop) if(a[nw] - b[i] <= base) return 1;
return 0;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> T;
while(T --){
btop = 0;
cin >> n >> h >> r;
base = 4 * r * r;
F(i, 1, n) cin >> a[i].x >> a[i].y >> a[i].z;
sort(a + 1, a + n + 1);
F(i, 1, n) if(check(i)) b[++ btop] = a[i];
bool tag = 0;
G(i, btop, 1) if(b[i].z >= h - r) {tag = 1; break;}
if(tag) cout << "Yes\n";
else cout << "No\n";
}
return 0;
}

【2024.10.03】NOIP2024 赛前集训-刷题训练(5)的更多相关文章

  1. 10.24afternoon清北学堂刷题班

    /* 这是什么题... */ #include<iostream> #include<cstdio> #include<cstring> #include<q ...

  2. NOIp2018停课刷题记录

    Preface 老叶说了高中停课但是初中不停的消息后我就为争取民主献出一份力量 其实就是和老师申请了下让我们HW的三个人听课结果真停了 那么还是珍惜这次机会好好提升下自己吧不然就\(AFO\)了 Li ...

  3. LeetCode的刷题利器(伪装到老板都无法diss你没有工作)

    在工程效率大行其道的今天,如果不会写点代码以后也不容易在测试圈混下去.今天给大家推荐一个LeetCode的刷题利器,可以伪装到连你老板在这里走过去都无法确认你是在干活呢,还是在干活呢. LeetCod ...

  4. 18.9.10 LeetCode刷题笔记

    本人算法还是比较菜的,因此大部分在刷基础题,高手勿喷 选择Python进行刷题,因为坑少,所以不太想用CPP: 1.买股票的最佳时期2 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. ...

  5. leecode刷题(10)-- 旋转图像

    leecode刷题(10)-- 旋转图像 旋转图像 描述: 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维 ...

  6. LeetCode刷题模板(1):《我要打10个》之二分法

    Author       :  叨陪鲤 Email         : vip_13031075266@163.com Date          : 2021.01.23 Copyright : 未 ...

  7. 牛客网NOIP赛前集训营-提高组(第四场)B题 区间

    牛客网NOIP赛前集训营-提高组(第四场) 题目描述 给出一个序列 a1, ..., an. 定义一个区间 [l,r] 是好的,当且仅当这个区间中存在一个 i,使得 ai 恰好等于 al, al+1, ...

  8. 10.1综合强化刷题 Day6

    T1 排序 题目描述 小Z 有一个数字序列a1; a2; .... ; an,长度为n,小Z 只有一个操作:选 定p(1<p<n),然后把ap 从序列中拿出,然后再插⼊到序列中任意位置. ...

  9. NOI Online 赛前刷题计划

    Day 1 模拟 链接:Day 1  模拟 题单:P1042 乒乓球  字符串 P1015 回文数  高精 + 进制 P1088 火星人  搜索 + 数论 P1604 B进制星球  高精 + 进制 D ...

  10. ZJOI2019一轮停课刷题记录

    Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...

随机推荐

  1. RabbitMQ普通集群同一宿主机docker搭建

    1.准备3个节点安装rabbitmq,搭建集群(注意:每个节点启动间隔15~20s,如果启动失败,需删除宿主机文件重新启动) 2.宿主机文件目录手动创建,并设置可操作权限 准备宿主机文件目录 cd / ...

  2. loj6669 Nauuo and Binary Tree 题解

    https://loj.ac/p/6669 赛时做法 先 \(n-1\) 次问出深度 逐层考虑.slv(vector<int> a,vector<int> b) 表示在点集 \ ...

  3. 从0实现基于Linux socket聊天室-多线程服务器一个很隐晦的错误-2

    根据 <0 基于socket和pthread实现多线程服务器模型>所述,server创建子线程的时候用的是以下代码: pconnsocke = (int *) malloc(sizeof( ...

  4. ZABBIX Maps(拓扑图) 数据可视化

    本篇文章将介绍如何利用zabbix内置 Maps模块展示主机数据指标以及如何关联触发器 构建业务地图让异常指标更加直观呈现 下面我将从网络设备.服务器和vmware esxi和IP主机去为大家解析za ...

  5. TwinCAT3 - 实现自己的Dictionary

    目录 1,前言 2,C#的字典 3,TwinCAT3的字典 定义功能块 添加方法 4,用起来 1,前言 C#有字典,TwinCAT没字典,咋办,自己写一个咯 2,C#的字典 C#的字典使用很简单,下面 ...

  6. LaTeX 编译 acmart 文档报错:hyperref must be loaded before hyperxmp.

    在编译一篇从 arXiv 下载的文档时遇到如下错误: Package hyperxmp Error: hyperref must be loaded before hyperxmp. 根据 GitHu ...

  7. ELK快速部署(踩坑记录、常见报错解决)及常用架构讲解

    ELK = Elasticserach + Logstash + kibana(包含但不仅限于) 简介: Elasticsearch:分布式搜索和分析引擎,具有高可伸缩.高可靠和易管理等特点.基于 A ...

  8. AutoFitTextureView Error inflating class

    报错: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解 ...

  9. Linux下载安装jdk1.8

    Linux下载安装jdk1.8 一.下载 wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=a ...

  10. SuperMap iServer&iPortal&iEdge结合CAS 5.3服务器实现单点登录

    2023-10-19 更新,由于阿里云maven镜像仓库里缺失了很多CAS5.3 依赖,如果缺少可以用附件里的同步到本地仓库 链接:https://pan.baidu.com/s/14DhRci_Am ...