【做题记录】贪心--提高组

news/2025/10/23 22:04:01/文章来源:https://www.cnblogs.com/zhangxyhp/p/19161750

A. Monotone Subsequence

有点 Ad-hoc。

\(i\) 次查询,直接询问当前未被删去的所有点。如果回答 \(\ge n+1\),那么直接输出;否则将回答的这些点标一个级别 \(i\)。最后一次询问之后还剩下的标为 \(n+1\)。根据鸽笼原理,如果最后没剩下,那么中间必然有一次回答 \(\ge n+1\)

可以发现,对于每个级别为 \(i\) 的位置,在其之前必然有一个级别为 \(i-1\) 的位置 \(j\),且 \(p_j\) 是必然比 \(p_i\) 大的。于是我们连边,跑一个 DAG 上 DP 即可。

Code
#include<bits/stdc++.h>
#define ll long long
#define il inline
#define pb push_back
using namespace std;
namespace asbt{
const int maxn=1e4+5;
int T,n,a[maxn],f[maxn],g[maxn];
set<int> st;
vector<int> e[maxn];
queue<int> q;
il void print(int u){if(!u){printf("! ");return ;}print(g[u]);printf("%d ",u);
}
int main(){scanf("%d",&T);while(T--){scanf("%d",&n);st.clear();for(int i=1;i<=n*n+1;i++){st.insert(i),e[i].clear();}for(int i=1;i<=n;i++){printf("? %d ",(int)st.size());for(int j:st){printf("%d ",j);}puts(""),fflush(stdout);int c;scanf("%d",&c);if(c>=n+1){printf("! ");for(int j=1,x;j<=c;j++){scanf("%d",&x);if(j<=n+1){printf("%d ",x);}}puts(""),fflush(stdout);goto togo;}for(int j=1,x;j<=c;j++){scanf("%d",&x);a[x]=i,st.erase(x);}}for(int i:st){a[i]=n+1;}for(int i=1;i<=n*n+1;i++){if(a[i]==1){q.push(i),f[i]=1,g[i]=0;}else{for(int j=i-1;j;j--){if(a[j]==a[i]-1){e[j].pb(i);break;}}}}while(q.size()){int u=q.front();q.pop();for(int v:e[u]){q.push(v);f[v]=f[u]+1,g[v]=u;}}for(int i=1;i<=n*n+1;i++){if(f[i]==n+1){print(i);puts(""),fflush(stdout);break;}}togo:;}return 0;
}
}
int main(){return asbt::main();}

B. Yet Another MEX Problem

重要结论\(\sum[a_i>\operatorname{mex}(a)]=\max\limits_{x\notin a}\sum[a_i>x]\)。证明显然。

于是我们考虑在移动 \(r\) 时对每个 \(x\) 维护右面那个式子。设最后出现 \(x\) 的位置为 \(p_x\),我们维护的就是 \([p_x+1,r]\) 中大于 \(x\) 的数的个数,这是方便用线段树维护的。

Code
#include<bits/stdc++.h>
#define ll long long
#define il inline
#define lid id<<1
#define rid id<<1|1
using namespace std;
namespace asbt{
const int maxn=3e5+5;
int T,n,a[maxn],tr[maxn<<2],tag[maxn<<2];
il void pushup(int id){tr[id]=max(tr[lid],tr[rid]);
}
il void pushtag(int id,int v){tr[id]+=v,tag[id]+=v;
}
il void pushdown(int id){if(tag[id]){pushtag(lid,tag[id]);pushtag(rid,tag[id]);tag[id]=0;}
}
il void build(int id,int l,int r){tr[id]=tag[id]=0;if(l==r){return ;}int mid=(l+r)>>1;build(lid,l,mid);build(rid,mid+1,r);
}
il void upd(int id,int l,int r,int p){if(l==r){tr[id]=0;return ;}pushdown(id);int mid=(l+r)>>1;if(p<=mid){upd(lid,l,mid,p);}else{pushtag(lid,1);upd(rid,mid+1,r,p);}pushup(id);
}
int main(){ios::sync_with_stdio(0),cin.tie(0);cin>>T;while(T--){cin>>n;build(1,0,n);for(int i=1;i<=n;i++){cin>>a[i];upd(1,0,n,a[i]);cout<<tr[1]<<' ';}cout<<'\n';}return 0;
}
}
int main(){return asbt::main();}

C. Make Good

Ad-hoc。

先把 \(n\) 为奇数判掉。然后开始对脑电波寻找性质:

首先,所有的 (()) 都是可以随意移动的。比如 ((

  • (()\(\to\))))\(\to\))((
  • )((\(\to\))))\(\to\)(()
  • (((\(\to\)((((没变但等于是动了)

所以我们先用栈把所有的 (()) 找出来,设有 \(cnt\) 个。剩下的字符串有以下三种可能:

  1. ()()()...()
  2. )()()()...()(
  3. 空串

那么如果 \(cnt\) 为奇数则必然无解,如果为偶数那么可以在这个串左右各加 \(\frac{cnt}{2}\)(())。当然如果 \(cnt=0\) 那么第二种情况就不成立。

Code
#include<bits/stdc++.h>
#define ll long long
#define il inline
using namespace std;
namespace asbt{
const int maxn=2e5+5;
int T,n,top,cnt;
char stk[maxn];
string s;
int main(){ios::sync_with_stdio(0),cin.tie(0);cin>>T;while(T--){cin>>n>>s;if(n&1){cout<<-1<<'\n';continue;}cnt=top=0;for(int i=0;i<n;i++){if(!top){stk[++top]=s[i];}else if(stk[top]==s[i]){cnt++,top--;}else{stk[++top]=s[i];}}if(cnt&1){cout<<-1<<'\n';}else if(!cnt&&stk[1]==')'){cout<<-1<<'\n';}else{for(int i=1;i<=cnt>>1;i++){cout<<"((";}for(int i=1;i<=top;i++){cout<<stk[i];}for(int i=1;i<=cnt>>1;i++){cout<<"))";}cout<<'\n';}}return 0;
}
}
int main(){return asbt::main();}

D. Long Journey

\(len=\operatorname{lcm}(a)\)。显然 \(len\le2520\)。称走 \(len\) 格为走了一个周期。

考虑整个过程,就是走 \(\lfloor\frac{m}{len}\rfloor\) 个周期,然后再走 \(m\bmod len\) 步。考虑压缩前面那些周期的过程。枚举进入这个周期前的时刻模 \(n\) 的值 \(i\),我们希望求出此状态下走一个周期的用时。模拟一遍这个周期的过程即可。

模拟的过程是一个贪心:如果下一格在下一秒是陷阱,那就等一秒,否则就走过去。如果在一格等待了 \(n\) 秒还是没走,那么无解。贪心的正确性在于不会出现两个相邻的格子同时是陷阱的情况。在每个格子都最多等待 \(n\) 次,所以单次模拟的时间复杂度是 \(O(n\times len)\) 的。这个预处理的总时间是 \(O(n^2\times len)\)

于是我们就可以快速计算了。走周期这个过程显然可合并,于是我们对走周期这个过程做快速幂。合并两个过程是 \(O(n)\) 的,这一部分时间复杂度 \(O(n\log\lfloor\frac{m}{len}\rfloor)\)。然后再类似上面的方式模拟最后一小段即可。

Code
#include<bits/stdc++.h>
#define int long long
#define il inline
#define gcd __gcd
using namespace std;
namespace asbt{
const int inf=1e18;
int T,n,m,a[12],b[12];
struct juz{int a[12];il int&operator[](int x){return a[x];}il juz operator*(juz b)const{juz c;for(int i=0;i<n;i++){c[i]=min(a[i]+b[(i+a[i])%n],inf);}return c;}
}bas;
il int calc(int t,int len){int p=0,res=0;while(p<len){p++;int cnt=0;t=t%n+1,res++;while(p%a[t]==b[t]){if(cnt==n){return inf;}t=t%n+1,cnt++,res++;}}return res;
}
il juz qpow(juz x,int y){juz res;for(int i=0;i<n;i++){res[i]=0;}while(y){if(y&1){res=res*x;}x=x*x,y>>=1;}return res;
}
int main(){ios::sync_with_stdio(0),cin.tie(0);cin>>T;while(T--){cin>>n>>m;int len=1;for(int i=1;i<=n;i++){cin>>a[i];len=len/gcd(len,a[i])*a[i];}for(int i=1;i<=n;i++){cin>>b[i];}if(m<len){int ans=calc(0,m);cout<<(ans>=inf?-1:ans)<<'\n';continue;}for(int i=0;i<n;i++){bas[i]=calc(i,len);
//			cout<<bas[i]<<' ';}
//		cout<<'\n';int ans=qpow(bas,m/len)[0];ans=ans+calc(ans%n,m%len);cout<<(ans>=inf?-1:ans)<<'\n';}return 0;
}
}
signed main(){return asbt::main();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/944716.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

latex输入公式

输入不换行公式:点击查看代码 \begin{equation}\label{eq:2}u_{exact} = \sin(x) - \frac{1}{4} \sin(4x) + \frac{1}{8} \sin(8x) - \frac{1}{16} \sin(16x) + \frac{1}{24} \sin(24x) - \frac{1}{48} \sin(48x) + …

【为美好CTF献上祝福】 New Star 2025 逆向笔记

Re Week1 Strange Base 乍一看是个正常的 base64 加密点进 base64 函数一看,发现 base64 的表被换了。

XXL-JOB(5)

XXL-JOB(5) 表结构分析 xxl_job_lock:任务调度锁表; xxl_job_group:执行器信息表,维护任务执行器信息; xxl_job_info:调度扩展信息表:用于保存XXL-JOB调度任务的扩展信息,如任务分组、任务名、机器地址、执行…

蛋白表达原理与关键要素解析

一、蛋白表达的基本原理 蛋白表达(Protein Expression) 是指细胞根据遗传信息合成蛋白质的过程。在自然状态下,DNA 上的基因通过 转录(Transcription) 产生信使 RNA(mRNA),随后经过 翻译(Translation) 在核糖…

顾雅南的声音美化课堂

下载地址 https://8ma.co/res/L7AZ255U ◀.zstitle { width: 280px; text-align: center; font-size: 26px } .zsimgweixin { width: 280px } .zsimgali { width: 280px; padding: 0px 0px 50px 0px } .zsleft { floa…

Ramanujan Master Theorem

:::note[前置知识] 这篇文章需要用到复数以及一些变换。如果你不会复数,可以参考这篇文章。 如果你不会变换,可以参考这篇文章。::: 位移算符 我们定义:\(D\equiv \frac{\mathrm d}{\mathrm dx}\),考虑 \[e^D=\sum…

【周记】2025.10.13~2025.10.19

2025.10.13~2025.10.19 周记不是太好的一周,随便说说两句吧。 ① 这一周非常非常的累...... 我们是周二、周四晚上(还有周六一整天哈)会上信息学竞赛,搞得我疲惫不堪。我们先是学了矩阵乘法,然后又打了一场模拟赛…

C++案例 自定义数组

#include <string> #include <iostream> #include <algorithm> #include <initializer_list> using namespace std;template<class T> class myArray {// 类模板 友元 重载 外部类实现/…

20251023周四日记

20251023周四日记今天心情好多了,项目终于快完事了。 今日: 1.早上买个早点肉夹馍来组里吃,来时正好碰见师姐收签字。更新了财政系统,搜了个nb的VLM综述。和博、耀对接好明天找他们去。 2.中午不老饿的,呆到两点去…

10.23《程序员修炼之道 从小工到专家》第二章 注重实效的途径 - GENGAR

软件开发需遵循多类核心原则,以提升效率、降低风险并保障代码质量。 DRY 原则(Don’t Repeat Yourself)要求系统中每项信息有单一权威表示,可避免重复带来的维护难题。重复主要分四类:强加的重复可通过方法规避,…

玩转单片机之智能车小露——LED闪烁实战

用单片机点亮一颗LED非常简单,让一颗LED闪烁也很简单,比如写一段下面这样的程序: while(1){ // 无限循环LED1 = 0; // 点亮LEDdelay_ms(300); // 延时300msLED1 = 1; // 熄灭LEDdelay_ms(300); // 延…

ord() 函数

ord() 函数以一个字符(长度为 1 的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError 的异常。 ord() 函数的语法: ord(c)…

2025.10.23总结 - A

今天上了数据结构还有体育,加油

树状数组求逆序对

统计对于每个i<j,求a[i]>a[j]的数量 在每一次更新(update)树状数组时,以元素的值作为树状数组的索引,更新的值为 +1,代表个数。 在每一次获取(query)逆序对数时,存在于树状数组中的元素的索引值都比当前…

大模型 | VLA 初识及在自动驾驶场景中的应用

一、VLA 简介 1.1 VLA 定义 VLA (Vision Language Action)是一种多模态机器学习模型,结合了视觉、语言和动作三种能力,旨在实现从感知输入直接映射到控制动作的完整闭环能力。VLA 强调一体化多模态端到端架构,非感…

Redis中的分布式锁之SETNX底层实现

https://blog.csdn.net/qq_39032307/article/details/148683477

2025家纺摄影公司推荐,南通鼎尚摄影专注产品视觉呈现

2025家纺摄影公司推荐,南通鼎尚摄影专注产品视觉呈现 家纺摄影行业面临的技术挑战 随着电商行业的蓬勃发展,家纺摄影行业正面临着前所未有的技术挑战。据统计,超过70%的线上消费者表示,产品图片质量直接影响其购买…

ExPRT.AI如何预测下一个将被利用的漏洞

本文详细介绍了CrowdStrike Falcon Exposure Management中的ExPRT.AI引擎如何利用实时对手信号、观测到的攻击行为以及基于专有威胁情报训练的AI来预测最可能被利用的漏洞,帮助安全团队优先处理最关键的安全风险。How…

求函数

求函数 题目描述 牛可乐有 $n$ 个一次函数,第 $i$ 个函数为 $f_i(x) = k_i \times x + b_i$。 牛可乐有 $m$ 次操作,每次操作为以下二者其一:$1$ $i$ $k$ $b$ 将 $f_i(x)$ 修改为 $f_i(x) = k \times x + b$。 $2$ …