ABC365
written by Ulysses
赛时通过:A、B、C。
赛后补题:D、E。
A
依题判断即可。
#include<bits/stdc++.h> using namespace std; int y; int main(){ cin>>y; if(y%4!=0) cout<<365; if(y%4==0&&y%100!=0) cout<<366; if(y%100==0&&y%400!=0) cout<<365; if(y%400==0) cout<<366; }
B
排序即可。
#include<bits/stdc++.h> #define int long long using namespace std; const int N=1e2+5; int n; pair<int,int> a[N]; signed main(){ cin>>n; for(int i=1;i<=n;i++) cin>>a[i].first,a[i].second=i; sort(a+1,a+n+1); cout<<a[n-1].second; return 0; }
C
显然 \(x\) 越大,总费用越大,具有单调性。二分即可求出最大的 \(x\)。
当 $ \sum a_i > M$ 时,\(x\) 便可无限大。
#include<bits/stdc++.h> #define int long long using namespace std; const int N=2e5+5; int n,m,a[N]; bool check(int x){ int s=0; for(int i=1;i<=n;i++) s+=min(x,a[i]); return s<=m; } signed main(){ ios::sync_with_stdio(0); cin>>n>>m; int s=0; for(int i=1;i<=n;i++) cin>>a[i],s+=a[i]; if(s<=m) cout<<"infinite",exit(0); int l=0,r=m+1; while(l+1<r){ int mid=(l+r)>>1; if(check(mid)) l=mid; else r=mid; } cout<<l; return 0; }
D
首先贪心是错误的。详情见 这份 Hack。
然后考虑 dp。因为过于简单,所以具体细节见代码。
#include<bits/stdc++.h> #define int long long using namespace std; const int N=2e5+5; int n; string s; int dp[N][3]; //0/1/2:R/P/S //R->S S->P P->R signed main(){ ios::sync_with_stdio(0); cin>>n>>s,s="#"+s; if(s[1]=='R') dp[1][0]=0, dp[1][1]=1, dp[1][2]=-1e9; else if(s[1]=='P') dp[1][0]=-1e9, dp[1][1]=0, dp[1][2]=1; else dp[1][0]=1, dp[1][1]=-1e9, dp[1][2]=0; for(int i=2;i<=n;i++){ if(s[i]=='R') dp[i][0]=max(dp[i-1][1],dp[i-1][2]), dp[i][1]=max(dp[i-1][0],dp[i-1][2])+1; else if(s[i]=='P') dp[i][1]=max(dp[i-1][0],dp[i-1][2]), dp[i][2]=max(dp[i-1][0],dp[i-1][1])+1; else dp[i][0]=max(dp[i-1][1],dp[i-1][2])+1, dp[i][2]=max(dp[i-1][0],dp[i-1][1]); } cout<<max({dp[n][0],dp[n][1],dp[n][2]}); }
E
灵茶八题 T3。
看到异或运算,考虑二进制拆位。
考虑异或的一个性质:
\[S_r \oplus S_{l-1} = \oplus ^ {r} _ {i=l} A_i
\]
其中:
\[S_i=\oplus ^ {i} _ {j=1} A_j
\]
(这是因为,\(S_r\) 与 \(S_{l-1}\) 的相同部分会被消去)
于是,我们求出 \(S\) 数组(\(n+1\) 位),其中第 \(0\) 位是为了提取长度为 \(1\) 的子数组。
能提取出一个子数组,当且仅当 \(S_r\) 与 \(S_{l-1}\) 的某一位的异或值为 \(1\),不然这俩的贡献就是 \(0\)。
考虑二进制拆位。对于 \(S\) 数组中的每一位,只有两位分别是 \(0,1\) 时,才会有贡献。
于是我们统计出每一位中 \(1\) 的个数 \(x\),则 \(0\) 的个数即为 \(n+1-x\),通过乘法原理计算可得贡献即为 \((n+1-x) \times x\),再乘上 \(2^j\) 即为当前位的贡献,累加即可。
#include<bits/stdc++.h> #define int long long using namespace std; const int N=2e5+5,M=31; int n,ans; int a[N],s[N]; signed main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>a[i],s[i]=s[i-1]^a[i]; } int ans=0; for(int j=0;j<31;j++){ int cnt=0; for(int i=0;i<=n;i++) cnt+=s[i]>>j&1; ans+=(cnt)*(n+1-cnt)*(1<<j); } for(int i=1;i<=n;i++) ans-=a[i]; cout<<ans; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话