ABC393
赛时通过:A,B,C
赛后通过:D,E,F
D
做法很多样化,我的想法就是取所有 1
的位置的中位数然后把它们移到那个地方周围,具体见代码。你说的对,这题非常简单,但是我忘记用缺省源了导致忘开 LL,赛后 eps s 通过。
实现
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stdlib.h> #include <vector> #include <queue> #include <cmath> #include <stack> #include <map> #include <set> #define int long long using namespace std; const int N=5e5+5; int n; int tot,a[N]; string s; signed main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n>>s,s='#'+s; for(int i=1;i<=n;i++) if(s[i]=='1') a[++tot]=i; int k=(tot&1?(tot+1)/2:tot/2),ans=0; int last=a[k]-1; for(int i=k-1;i>=1;i--,last--) ans+=last-a[i]; last=a[k]+1; for(int i=k+1;i<=tot;i++,last++) ans+=a[i]-last; cout<<ans<<'\n'; return 0; }
总结:开 LL。
E
令答案为 \(x\),我们考虑满足什么条件的 \(x\) 可以成为答案:
-
\(x \mid A_i\)
-
\(A\) 里边有恰好 \(K\) 个数被 \(x\) 整除。
-
最大。
观察到 \(A_i \le 10^6\),这提示我们可以枚举答案再去检验它。
第一个比较简单,直接枚举 \(x\) 倍数即可。
第二个的话,我可以预处理出每个数在 \(A\) 中出现的次数,然后对于每一个 \(x\) 的倍数累加这个次数即可统计出 \(A\) 中有多少个数可以被 \(x\) 整除。
第三个直接取 \(\max\) 就可以了。
然后我们注意到这个时间复杂度实际上是调和级数的,而非平方级别,因此可以承受。
实现
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stdlib.h> #include <vector> #include <queue> #include <cmath> #include <stack> #include <map> #include <set> #define int long long using namespace std; const int N=2e6+5; int n,k,a[N]; int m=-1e9,cnt[N],mcnt[N],ans[N]; signed main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n>>k; for(int i=1;i<=n;i++) cin>>a[i],m=max(m,a[i]),cnt[a[i]]++; for(int i=1;i<=m;i++) for(int j=i;j<=m;j+=i) mcnt[i]+=cnt[j]; for(int i=1;i<=m;i++) for(int j=i;j<=m;j+=i) if(mcnt[i]>=k) ans[j]=max(ans[j],i); for(int i=1;i<=n;i++) cout<<ans[a[i]]<<'\n'; return 0; }
总结:刻画答案法。
F
一眼 dp。
多组询问,考虑将询问离线,挂在 \(r\) 上,这样就可以一边 dp 一边回答询问了。
因为题目要求 LIS 中每个数都最多是 \(X_i\),这等价于最末尾的数 \(\le X_i\),于是定义 \(dp_i\) 表示长度为 \(i\) 的 LIS 末尾最小是多少。
转移:每次在 \(dp\) 中找第一个 \(\ge a_i\) 的数,然后用 \(a_i\) 替代它。
初始:均为 \(\infty\)。
具体细节见代码。
实现
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stdlib.h> #include <vector> #include <queue> #include <cmath> #include <stack> #include <map> #include <set> #define int long long using namespace std; const int N=2e5+5; int n,q,a[N]; struct QUERY{ int id,x; }; vector<QUERY> qs[N]; int ans[N],dp[N]; signed main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n>>q; for(int i=1;i<=n;i++) cin>>a[i],dp[i]=1e10; for(int i=1;i<=q;i++){ int r,x; cin>>r>>x; qs[r].push_back({i,x}); } for(int i=1;i<=n;i++){ int p=lower_bound(dp+1,dp+n+1,a[i])-dp; dp[p]=a[i]; for(auto [id,x]:qs[i]) ans[id]=upper_bound(dp+1,dp+n+1,x)-dp-1; } for(int i=1;i<=q;i++) cout<<ans[i]<<'\n'; return 0; }
总结:询问离线思想、dp 按位考虑思想。
G
待补。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!