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;
}
posted @   _XOFqwq  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示