Codeforces Round #796 (Div. 2)
A
核心思路
我们看这个数据范围肯定很自然的想到了位运算,题目是要我们找到最小的y。首先我们需要了解的就是与运算和异或运算的实质。
与运算:一个数与上一个数结果肯定是会让这个数变小。
异或运算:相当于不进位的加法。
首先一个性质很强的就是我们的与运算,我们知道必须从x的末尾的1代表的那个数开始枚举。因为之前的相与都是0.
// Problem: A. Cirno's Perfect Bitmasks Classroom
// Contest: Codeforces - Codeforces Round #796 (Div. 2)
// URL: https://codeforces.com/contest/1688/problem/A
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define NO {puts("NO") ; return ;}
#define YES {puts("YES") ; return ;}
#define endl "\n"
#define int long long
int lowbit(int x)
{
return x&-x;
}
void solve()
{
int x;
cin>>x;
int w=lowbit(x);
while(!(w&x)||!(x^w))
w++;
cout<<w<<endl;
}
signed main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
}
B
核心思路
我们只需要奇数加上偶数等于奇数这个性质就好了。
所以当我们的排列里面有奇数,那么不断地使用操作1合并就好了。
如果没有的话,就先使用操作二制造出来奇数,然后再使用操作一合并。
// Problem: B. Patchouli's Magical Talisman
// Contest: Codeforces - Codeforces Round #796 (Div. 2)
// URL: https://codeforces.com/contest/1688/problem/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define NO {puts("NO") ; return ;}
#define YES {puts("YES") ; return ;}
#define endl "\n"
#define int long long
void solve()
{
int n;
cin>>n;
vector<int> a(n);
int flag=0,cnt=0;
int ans=0x3f3f3f3f;
for(int i=0;i<n;i++)
{
cin>>a[i];
if(a[i]&1)
{
cnt++;
}
else
{
int minn=a[i];
int t=0;
while(minn%2==0)
{
minn/=2;
t++;
}
ans=min(ans,t);
}
}
if(cnt)
{
cout<<n-cnt<<endl;
}
else
{
cout<<ans+n-1<<endl;
}
}
signed main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
}
C
核心思路
其实这个题目很简单,就是要我们由最后的状态递推出来初态。直接模拟的话做起来可能比较麻烦,可以直接观察样例模拟出来规律,其实发现也就是一个异或操作。
// Problem: C. Manipulating History
// Contest: Codeforces - Codeforces Round #796 (Div. 2)
// URL: https://codeforces.com/contest/1688/problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define NO {puts("NO") ; return ;}
#define YES {puts("YES") ; return ;}
#define endl "\n"
#define int long long
void solve()
{
int n;
char c=0;
cin>>n;
n=2*n+1;
while(n--)
{
string s;
cin>>s;
for(auto x:s)
c^=x;
}
cout<<c<<endl;
}
signed main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
}
D
核心思路
首先分析以下两种情况:
- \(k\le n\).在这种我们可以从k+1这个节点开始走。然后是可以把长度为k的上面已有的蘑菇采摘完:\(max\sum_{j=i-k+1}^{i}a[j]\)。但是额外的蘑菇怎么算呢,我们其实可以发现他是符合等差数列的:\(k*(k+1)/2\).
- \(k\ge n\).这里我们可以知道的是我们肯定已经把已有的蘑菇给采摘完了,所以我们应该如何去考虑额外的蘑菇达到最大化。首先假设\(b_i是我们在k-i分钟所在的一个位置\),这里可以得出来一个i的取值范围:\(0\le i \le n-1\).我们可以知道当前位置至少会遗漏\(\sum_{i=0}^{n-1} (n-i)=\frac{n*(n+1)}{2}\).这么多蘑菇。这个还是比较好理解的,因为我们当前i分钟最多清理i个位置。我们只需要让我们的\(b_i=i+1\)就可以取到最小值。然后在使用总共长出来的蘑菇\(nk-这个最小值就好了\).注意这个只是额外的,还是加上本来的。
// Problem: D. The Enchanted Forest
// Contest: Codeforces - Codeforces Round #796 (Div. 2)
// URL: https://codeforces.com/contest/1688/problem/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define NO {puts("NO") ; return ;}
#define YES {puts("YES") ; return ;}
#define endl "\n"
#define int long long
void solve()
{
int n,k;
cin>>n>>k;
vector<int> s(n+1);
for(int i=1;i<=n;i++)
{
cin>>s[i];
s[i]+=s[i-1];
}
if(k>=n)
{
int ans=(2*k-(n+1))*n/2+s[n];
cout<<ans<<endl;
}
else
{
int mx=s[k];
for(int i=k+1;i<=n;i++)
mx=max(mx,s[i]-s[i-k]);
cout<<mx+k*(k-1)/2<<endl;
}
}
signed main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
}

浙公网安备 33010602011771号