西安交大多校联训NOIP1模拟赛题解
西安交大多校联训NOIP1模拟赛题解
- T1 秘境
- 形式化题意
- 思路
- 代码(丑陋)
- T2 礼物
- 形式化题意
- 思路
- 代码(实现)
- T3 小盒子的数论
- 形式化题意
- 思路
- 代码(分讨)
- T4 猫猫贴贴(CF997E)
- 形式化题意
- 思路
- 代码(深奥)
T1 秘境
形式化题意
求 ∑ i = 1 n ⌊ i ⌋ \sum\limits_{i=1}^{n}\lfloor i\rfloor i=1∑n⌊i⌋ , 1 ≤ n ≤ 1 0 18 1\leq n\leq 10^{18} 1≤n≤1018
思路
看到根号直接想到根号分块。直接将原式转换为 [ ∑ i = 1 ⌊ n ⌋ − 1 ( 2 i + 1 ) ] + P [\sum\limits_{i=1}^{\lfloor \sqrt n \rfloor-1}(2i+1)]+P [i=1∑⌊n⌋−1(2i+1)]+P,这个式子直接用公式就可以了, P P P 的散块 O ( 1 ) O(1) O(1) 算。
代码(丑陋)
//Syt forever!
#include<bits/stdc++.h>
#define int __int128
#define ll long long
using namespace std;const int mod=998244353;
ll c;
int n;
signed main(){scanf("%lld",&c);n=c;int a=1,b=2,c=-n;int delta=b*b-4*a*c;delta=sqrtl(delta);ll r=delta;int p=delta-b;p/=2*a;int ans=p*(p+1)*(2*p+1)/3+(1+p)*p/2;int num=(3+2*p+1)*p/2;num=n-num;++p;ans+=num*p;ans%=mod;ll tot=ans;printf("%lld\n",tot);return 0;
}
T2 礼物
形式化题意
有 n n n 件物品,第 i i i 个礼物价格为 w i w_i wi 元,价值为 v i v_i vi 。
T T T 次询问,每次有 m m m 元,用这些钱购买奇数 q i q_i qi 件物品,对于每个询问计算出购买 q i q_i qi 件物品的中位数的最大值。若无法购买输出 − 1 -1 −1。
思路
首先不难想到若购买物品越多中位数最大值越小,假如我们先钦定一个中位数,去检查其是否可行,无非检测 ≥ \ge ≥ 中位数和 < < < 中位数两部分是否合法。这个其实直接可以权值线段树维护,将查询离线,两棵权值线段树就可以了。
代码(实现)
//Syt forever!
#include<bits/stdc++.h>
#define int long long
using namespace std;const int maxn=5e5+10;
const int maxm=1e6+10;
int n,m,T,cnt;
int c[maxn],ans[maxn];
struct node{int v,w;
}a[maxn];
struct vertex{int x,op;
}e[maxn];
struct Segment{int l,r;int num,sum;
}t[5][maxm<<2];
inline void ipt(){scanf("%lld%lld%lld",&n,&m,&T);for(int i=1;i<=n;i++){scanf("%lld%lld",&a[i].v,&a[i].w);c[i]=a[i].v;}for(int i=1;i<=T;i++){scanf("%lld",&e[i].x);e[i].op=i;}
}
inline bool cmp1(node nx,node ny){return nx.v<ny.v;}
inline bool cmp2(vertex nx,vertex ny){return nx.x<ny.x;}
inline bool cmp3(vertex nx,vertex ny){return nx.op<ny.op;}
inline void init(){sort(c+1,c+n+1);cnt=unique(c+1,c+n+1)-c-1;sort(a+1,a+n+1,cmp1);sort(e+1,e+T+1,cmp2);
}
inline void build(int op,int i,int l,int r){t[op][i].l=l,t[op][i].r=r;if(l==r)return ;int mid=l+r>>1;build(op,i<<1,l,mid);build(op,i<<1|1,mid+1,r);
}
inline void upd(int op,int i){t[op][i].num=t[op][i<<1].num+t[op][i<<1|1].num;t[op][i].sum=t[op][i<<1].sum+t[op][i<<1|1].sum;
}
inline void change(int op,int i,int l,int r,int x){if(t[op][i].l>r||t[op][i].r<l)return ;if(l<=t[op][i].l&&t[op][i].r<=r){t[op][i].num+=x;t[op][i].sum+=x*l;return ;}change(op,i<<1,l,r,x);change(op,i<<1|1,l,r,x);upd(op,i);
}
inline int query(int op,int i,int k){if(k==0)return 0;if(t[op][i].l==t[op][i].r){int u=min(k,t[op][i].num);return u*t[op][i].l;}if(t[op][i<<1].num<=k)return t[op][i<<1].sum+query(op,i<<1|1,k-t[op][i<<1].num);return query(op,i<<1,k);
}
inline void solve(){int pos=cnt,s;for(int i=1;i<=n;i++){if(a[i].v==c[cnt])change(1,1,a[i].w,a[i].w,1);else {change(0,1,a[i].w,a[i].w,1);s=i;}}for(int i=1;i<=T;i++){if(e[i].x==e[i-1].x)continue;if(ans[e[i-1].x]==-1){ans[e[i].x]=-1;continue;}int l=(e[i].x-1)/2;if(t[0][1].num<l){ans[e[i].x]=-1;continue;}while(1){int p=query(0,1,l)+query(1,1,l+1);if(t[0][1].num<l){ans[e[i].x]=-1;break;}if(t[1][1].num>=l+1){if(p<=m){ans[e[i].x]=c[pos];break;}}--pos;int ns=0;for(int j=s;j>=1;j--){if(a[j].v==c[pos]){change(1,1,a[j].w,a[j].w,1);change(0,1,a[j].w,a[j].w,-1); }else{ns=j;break;}}s=ns;}}
}
inline void opt(){sort(e+1,e+T+1,cmp3);for(int i=1;i<=T;i++)printf("%lld\n",ans[e[i].x]);
}
signed main(){ipt();init();build(0,1,1,1000000);build(1,1,1,1000000);solve();opt();return 0;
}
T3 小盒子的数论
形式化题意
当给定 T T T 组数据,每组数据包括一个进制数 m m m 和一个字符串 s s s 。其中 s s s 表示的是一个 m m m 进制数,其中数据相同字母表示相同的数字,不同字母表示不同的数字,且 s s s 表示的数字不包含前导零。求 s s s 表示的所有可能的数字的最大公约数,用十进制表示。
思路
设出现字符的种类数为 c n t cnt cnt。
若 m = 2 m=2 m=2 需要特判,此处略。
若 m ≠ 2 , c n t < m m\ne 2,cnt<m m=2,cnt<m,可以通过构造证明答案为每个字母出现数位的最大公约数。
若 m ≠ 2 , c n t = m m\ne 2,cnt=m m=2,cnt=m,若 m m m 为奇数,答案为 n − 1 2 \frac{n-1}{2} 2n−1;若 m m m 为偶数,答案为 n − 1 n-1 n−1。
代码(分讨)
//Syt forever!
#include<bits/stdc++.h>
#define int long long
using namespace std;const int maxn=260;
int t,n,cnt;
char s[maxn];
int op[maxn],a[maxn];
inline void solve(){cnt=0;memset(op,0,sizeof(op));memset(a,0,sizeof(a));scanf("%lld",&n);scanf("%s",s);int len=strlen(s);for(int i=len;i>=1;i--)s[i]=s[i-1];int c=1;for(int i=len;i>=1;i--){if(i!=len)c*=n;int u=(int)(s[i]);if(!op[u])op[u]=++cnt;a[op[u]]+=c;}if(n==2){if(len==1)printf("1\n");else {if(s[1]==s[2])printf("3\n");else printf("2\n");}return ;}if(cnt!=n){int ans=a[1];for(int i=2;i<=cnt;i++)ans=__gcd(ans,a[i]); printf("%lld\n",ans);} else {if(n%2==1)printf("%lld\n",(n-1)/2);else printf("%lld\n",n-1);}
}
signed main(){ scanf("%lld",&t);while(t--)solve();return 0;
}
T4 猫猫贴贴(CF997E)
形式化题意
长度为 n n n 的排列 a 1 , a 2 , ⋯ , a n a_1,a_2,\cdots,a_n a1,a2,⋯,an。 q q q 次询问,每次询问 [ l , r ] [l,r] [l,r] 子区间(不能为空)内部元素重新排序后连续的子区间数量。
思路
首先考虑被计算在答案的区间 [ l , r ] [l,r] [l,r] 的特征。
其充要条件为 max i = l r a i − min i = l r a i + 1 = r − l + 1 \max\limits_{i=l}^r a_i-\min\limits_{i=l}^ra_i+1=r-l+1 i=lmaxrai−i=lminrai+1=r−l+1,化简一下可以得到 max i = l r a i − min i = l r a i − r + l = 0 \max\limits_{i=l}^r a_i-\min\limits_{i=l}^ra_i-r+l=0 i=lmaxrai−i=lminrai−r+l=0。发现 max i = l r a i − min i = l r a i − r + l ≥ 0 \max\limits_{i=l}^r a_i-\min\limits_{i=l}^ra_i-r+l\ge 0 i=lmaxrai−i=lminrai−r+l≥0,想到可以记录这一坨式子的最小值和出现次数,进行计算答案。
对于区间问题有一个传统套路,按照区间右端点 r r r 从小到大排序,在处理到右端点为 r r r 时。我们只维护 [ i , r ] [i,r] [i,r] 的答案,历史答案记录。
对于 max \max max 和 min \min min 的更新,可以通过 2 2 2 个单调栈维护区间,每次通过单调栈去寻找出哪些 i i i构成的区间的 max \max max 和 min \min min 需要变化。
这个东西显然可以用线段树去维护,线段树维护 个量:
- m n mn mn,上面一坨式子的最小值。
- c n t cnt cnt,最小值次数。
- l a z y lazy lazy,区间加tag。
- a n s ans ans,历史答案。
- a n s ans ans_ l a z y lazy lazy,历史答案tag。
初始时对于线段树每个节点 t [ l , l ] . m n = l t[l,l].mn=l t[l,l].mn=l,每次右端点向右扩张 1 1 1 ,最大值单调栈处理,最小值单调栈处理,将对应 3 3 3 个线段树区间加,其中第二个第三个只会让区间最小值变大,之后往 t [ 1 , n ] . a n s t[1,n].ans t[1,n].ans_ l a z y lazy lazy 加一,查询的时候求 a n s ans ans 的和。
这样线段树正确性证明:若某个区间最小值变化,那么肯定在上一步pushdown,若无则说明这个区间是 [ 1 , n ] [1,n] [1,n]。pushdown时顺便将上一次的 a n s ans ans_ l a z y lazy lazy 以及 c n t cnt cnt 转换为 a n s ans ans。这样将开启新一轮的计算,所以这样的线段树不会出现错误。
代码(深奥)
//Syt forever!
#include<bits/stdc++.h>
#define int long long
using namespace std;const int maxn=2e5+10;
int n,q;
int a[maxn];
struct Segment{int l,r;int lazy;int mn,cnt;int ans,ans_lazy;
}t[maxn<<2];
//查询离线
struct node{int l,r,ans,op;
}c[maxn];
struct vertex{int l,r,x;
};
//单调栈
stack<vertex>st_mx,st_mi;
inline bool cmp1(node nx,node ny){return nx.r<ny.r;}
inline bool cmp2(node nx,node ny){return nx.op<ny.op;}
inline void ipt(){scanf("%lld",&n);for(int i=1;i<=n;i++)scanf("%lld",&a[i]);scanf("%lld",&q);for(int i=1;i<=q;i++){scanf("%lld%lld",&c[i].l,&c[i].r);c[i].op=i;}sort(c+1,c+q+1,cmp1);
}
inline void upd(int i){t[i].ans=t[i<<1].ans+t[i<<1|1].ans;if(t[i<<1].mn<t[i<<1|1].mn){t[i].mn=t[i<<1].mn;t[i].cnt=t[i<<1].cnt;}else if(t[i<<1].mn>t[i<<1|1].mn){t[i].mn=t[i<<1|1].mn;t[i].cnt=t[i<<1|1].cnt;}else {t[i].mn=t[i<<1].mn;t[i].cnt=t[i<<1].cnt+t[i<<1|1].cnt;}return ;
}
inline void build(int i,int l,int r){t[i].l=l,t[i].r=r;if(l==r){t[i].mn=l;t[i].cnt=1;return ;}int mid=l+r>>1;build(i<<1,l,mid);build(i<<1|1,mid+1,r);upd(i);
}
inline void modify1(int i,int x){t[i].mn+=x;t[i].lazy+=x;
}
inline void modify2(int i,int x){t[i].ans_lazy+=x;t[i].ans+=x*t[i].cnt;
}
inline void pushdown(int i){if(t[i].lazy!=0){modify1(i<<1,t[i].lazy);modify1(i<<1|1,t[i].lazy);t[i].lazy=0;}if(t[i].ans_lazy!=0){if(t[i<<1].mn==t[i].mn)modify2(i<<1,t[i].ans_lazy);if(t[i<<1|1].mn==t[i].mn)modify2(i<<1|1,t[i].ans_lazy);t[i].ans_lazy=0;}return ;
}
//区间加
inline void change(int i,int l,int r,int x){if(t[i].l>r||t[i].r<l)return ;if(l<=t[i].l&&t[i].r<=r){modify1(i,x);return ;}pushdown(i);change(i<<1,l,r,x);change(i<<1|1,l,r,x);upd(i);
}
inline int query(int i,int l,int r){if(t[i].l>r||t[i].r<l)return 0;if(l<=t[i].l&&t[i].r<=r)return t[i].ans;pushdown(i);return query(i<<1,l,r)+query(i<<1|1,l,r);
}
inline void solve(){int o=1;for(int i=1;i<=n;i++){change(1,1,n,-1);int l=i,r=i;while(!st_mx.empty()){vertex u=st_mx.top();if(u.x<a[i]){l=min(l,u.l);change(1,u.l,u.r,a[i]-u.x);st_mx.pop();}else break;}st_mx.push((vertex){l,r,a[i]});l=i,r=i;while(!st_mi.empty()){vertex u=st_mi.top();if(u.x>a[i]){l=min(l,u.l);change(1,u.l,u.r,u.x-a[i]);st_mi.pop();}else break;}st_mi.push((vertex){l,r,a[i]});modify2(1,1);while(c[o].r==i&&o<=q){c[o].ans=query(1,c[o].l,c[o].r);++o;}}
}
inline void opt(){sort(c+1,c+q+1,cmp2);for(int i=1;i<=q;i++)printf("%lld\n",c[i].ans);
}
signed main(){ipt();build(1,1,n);solve();opt();return 0;
}
相关文章:

西安交大多校联训NOIP1模拟赛题解
西安交大多校联训NOIP1模拟赛题解 T1 秘境形式化题意思路代码(丑陋) T2 礼物形式化题意思路代码(实现) T3 小盒子的数论形式化题意思路代码(分讨) T4 猫猫贴贴(CF997E)形式化题意思路代码(深奥&…...

数据结构(三)——栈和队列
一、栈和队列的定义和特点 栈:受约束的线性表,只允许栈顶元素入栈和出栈 对栈来说,表尾端称为栈顶,表头端称为栈底,不含元素的空表称为空栈 先进后出,后进先出 队列:受约束的线性表࿰…...

若依定制pdf生成实战
一、介绍 使用 Java Apache POI 将文字渲染到 Word 模板是一种常见的文档自动化技术,广泛应用于批量生成或定制 Word 文档的场景。使用aspose可以将word转成pdf从而达到定制化pdf的目的。 参考文档:java实现Word转Pdf(Windows、Linux通用&a…...
RCE联系
过滤 绕过空格 ● 进制绕过 题目练习 数字rce 使用$0执行bash,<<<将后面的字符串传递给左边的命令。 例如: <?php highlight_file(__FILE__); function waf($cmd) { $whiteList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \\, \, $, <]; $cmd_ch…...

c++STL-vector的模拟实现
cSTL-vector的模拟实现 vector的模拟实现基本信息构造函数析构函数返回容量(capacity)返回元素个数(size)扩容(reserve和resize)访问([])迭代器(**iterator**)…...
C++核心编程解析:模板、容器与异常处理全指南
文章目录 一、模板1.1 定义1.2 作用1.3 函数模版1.3.1 格式 1.4 类模版1.4.1 格式1.4.2 代码示例1.4.3 特性 二、容器2.1 概念2.2 容器特性2.3 分类2.4 向量vector2.4.1 特性2.4.2 初始化与操作2.4.3 插入删除 2.5 迭代器2.6 列表(list)2.6.1 遍历方式2.…...

在 Elasticsearch 中连接两个索引
作者:来自 Elastic Kofi Bartlett 解释如何使用 terms query 和 enrich processor 来连接 Elasticsearch 中的两个索引。 更多有关连接两个索引的查询,请参阅文章 “Elastic:开发者上手指南” 中的 “丰富数据及 lookup” 章节。 Elasticsea…...
Linux常用命令详解(下):打包压缩、文本编辑与查找命令
一、打包压缩命令 在Linux系统中,打包与压缩是文件管理的核心操作之一。不同的工具适用于不同场景,以下是最常用的命令详解: 1. tar命令 作用:对文件进行打包、解包、压缩、解压。 语法: tar [选项] [压缩包名] […...

使用 Watt toolkit 加速 git clone
一、前言 Watt toolkit 工具是我经常用于加速 GitHub 网页和 Steam 游戏商店访问的工具,最近想加速 git clone,发现可以使用 Watt toolkit 工具的代理实现。 二、查看端口 我这里以 Ubuntu 为例,首先是需要将加速模式设置为 System࿱…...

应急响应靶机——WhereIS?
用户名及密码:zgsf/zgsf 下载资源还有个解题.exe: 1、攻击者的两个ip地址 2、flag1和flag2 3、后门程序进程名称 4、攻击者的提权方式(输入程序名称即可) 之前的命令: 1、攻击者的两个ip地址 先获得root权限,查看一下历史命令记录&#x…...

Docke容器下JAVA系统时间与Linux服务器时间不一致问题解决办法
本篇文章主要讲解,通过docker部署jar包运行环境后出现java系统内时间与服务器、个人电脑真实时间不一致的问题原因及解决办法。 作者:任聪聪 日期:2025年5月12日 问题现象: 说明:与实际时间不符,同时与服务…...

【MCP】其他MCP服务((GitHub)
【MCP】其他MCP服务((GitHub) 1、其他MCP服务(GitHub) MCP广场:https://www.modelscope.cn/mcp 1、其他MCP服务(GitHub) 打开MCP广场 找到github服务 访问github生成令牌 先…...
SQL:MySQL函数:日期函数(Date Functions)
目录 时间是数据的一种类型 🧰 MySQL 常用时间函数大全 🟦 1. 获取当前时间/日期 🟦 2. 日期运算(加减) 🟦 3. 时间差计算 🟦 4. 格式化日期 🟦 5. 提取时间部分 Ƿ…...

内存 -- Linux内核内存分配机制
内存可以怎么用? kmalloc:内核最常用,用于频繁使用的小内存申请 alloc_pages:以页框为单位申请,物理内存连续 vmalloc:虚拟地址连续的内存块,物理地址不连线 dma_alloc_coherent:常…...

关于读写锁的一些理解
同一线程的两种情况: 读读: public static void main(String[] args) throws InterruptedException {ReentrantReadWriteLock lock new ReentrantReadWriteLock();Lock readLock lock.readLock();Lock writeLock lock.writeLock();readLock.lock();S…...

C++修炼:模板进阶
Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路! 我的博客:<但凡. 我的专栏:《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C修炼之路》 欢迎点赞,关注&am…...

android-ndk开发(10): use of undeclared identifier ‘pthread_getname_np‘
1. 报错描述 使用 pthread 获取线程名字, 用到 pthread_getname_np 函数。 交叉编译到 Android NDK 时链接报错 test_pthread.cpp:19:5: error: use of undeclared identifier pthread_getname_np19 | pthread_getname_np(thread_id, thread_name, sizeof(thr…...

UI自动化测试框架:PO 模式+数据驱动
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 1. PO 设计模式简介 什么是 PO 模式? PO(PageObject)设计模式将某个页面的所有元素对象定位和对元素对象的操作封装成…...
大小端的判断方法
大小端(Endianness) 是计算机存储多字节数据(如整数、浮点数)时的两种不同方式,决定了字节在内存中的排列顺序。 1. 大端(Big-Endian) 高位字节存储在低地址,低位字节存储在高地址。…...

Java笔记4
第一章 static关键字 2.1 概述 以前我们定义过如下类: public class Student {// 成员变量public String name;public char sex; // 男 女public int age;// 无参数构造方法public Student() {}// 有参数构造方法public Student(String a) {} }我们已经知道面向…...
DAY22kaggle泰坦尼克号
参考了机器学习实战进阶:泰坦尼克号乘客获救预测_天池notebook-阿里云天池 数据处理省略 直接上模型 5.12.1 一些数据的正则化 这里我们将Age和fare进行正则化: from sklearn import preprocessing scale_age_fare preprocessing.StandardScaler().…...

2025年渗透测试面试题总结-渗透测试红队面试八(题目+回答)
网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 渗透测试红队面试八 二百一十一、常见中间件解析漏洞利用方式 二百一十二、MySQL用户密码存储与加密 …...

MiniMind:3块钱成本 + 2小时!训练自己的0.02B的大模型。minimind源码解读、MOE架构
大家好,我是此林。 目录 1. 前言 2. minimind模型源码解读 1. MiniMind Config部分 1.1. 基础参数 1.2. MOE配置 2. MiniMind Model 部分 2.1. MiniMindForCausalLM: 用于语言建模任务 2.2. 主干模型 MiniMindModel 2.3. MiniMindBlock: 模型的基本构建块…...

如何进行前端性能测试?--性能标准
如何进行前端性能测试?–性能标准 前端性能测试指标: 首次加载阶段 场景:用户首次访问网页,在页面还未完全呈现各种内容和功能时的体验。重要指标及原因 首次内容绘制(FCP - First Contentful Paint)…...

通信网络编程——JAVA
1.计算机网络 IP 定义与作用 :IP 地址是在网络中用于标识设备的数字标签,它允许网络中的设备之间相互定位和通信。每一个设备在特定网络环境下都有一个唯一的 IP 地址,以此来确定其在网络中的位置。 分类 :常见的 IP 地址分为 I…...

Off-Policy策略演员评论家算法SAC详解:python从零实现
引言 软演员评论家(SAC)是一种最先进的Off-Policy策略演员评论家算法,专为连续动作空间设计。它在 DDPG、TD3 的基础上进行了显著改进,并引入了最大熵强化学习的原则。其目标是学习一种策略,不仅最大化预期累积奖励&a…...

热门CPS联盟小程序聚合平台与CPA推广系统开发搭建:助力流量变现与用户增长
一、行业趋势:CPS与CPA模式成流量变现核心 在移动互联网流量红利见顶的背景下,CPS(按销售付费)和CPA(按行为付费)模式因其精准的投放效果和可控的成本,成为企业拉新与用户增长的核心工具。 CPS…...
(自用)Java学习-5.9(Thymeleaf,自动装配,自定义启动器 )
一、Thymeleaf 模板技术 片段定义与复用 <!-- 声明片段 --> <div th:fragment"b1">...</div> <!-- 插入片段 --> <div th:insert"~{bottom :: b1}"></div> <!-- 追加内容 --> <div th:replace"~{botto…...

Linux系统管理与编程15:vscode与Linux连接进行shell开发
兰生幽谷,不为莫服而不芳; 君子行义,不为莫知而止休。 【1】打开vscode 【2】点击左下角连接图标 【3】输入远程连接 选择合适的操作系统 输入密码,就进入Linux环境的shell编程了。 在vscode下面粘贴拷贝更方便。比如 然后在v…...

RabbitMQ概念详解
什么是消息队列? 消息队列是一种在应用程序之间传递消息的技术。它提供了一种异步通信模式,允许应用程序在不同的时间处理消 息。消息队列通常用于解耦应用程序,以便它们可以独立地扩展和修改。在消息队列中,消息发送者将消息发送…...