这里的题基本都是老题,牛客每日一题上的题目集。
A
题意:这是cf上的一个老题,意思就是给你一个区间l,r,让你在l r里找一个数,这个数是这些数里二进制表示里1最多的数,并且输出这个数。
题解:贪心的想,我们要找的这个数是在l,r范围里,我们可以算出r总共有几位,然后让l上不是1的位置变为1,然后加上这个数,注意加上之后以后要小于r,我们要让1的数目尽量大的话,就要从小开始遍历,然后输出即可,另外需要注意范围。
#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
#define endl "\n"
using namespace std;
const int maxn = 2e5 + 5;
void solve(ll a,ll b)
{
ll c = a, d = b;
ll ans = 0;
while(d)
{
d /= 2;
ans++;
}
ll sum = a;
for (int i = 0; i < ans;i++)
{
if((a>>i)&1)
continue;
if(sum+(1ll<<i)<=b)
sum += (1ll << i);
}
cout << sum << endl;
}
int main()
{
int t;
cin >> t;
while(t--)
{
ll a, b;
cin >> a >> b;
solve(a, b);
}
}
C
题解:这是一个二分题,我们可以注意到如果在第i天不满足的话,那么后面的都会不满足,满足二分的单调性。所以我们用个前缀和和二分即可解决问题。
#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
using namespace std;
const int maxn = 1e6 + 5;
int n, m;
ll x[maxn], y[maxn], z[maxn];
ll a[maxn], b[maxn], c[maxn];
bool check(int k)
{
for (int i = 1; i <= n;i++)
{
z[i] = y[i];
}
for (int i = 1; i <= k;i++)
{
z[b[i]] -= a[i];
z[c[i] + 1] += a[i];
}
ll ans = 0;
for (int i = 1; i <= n;i++)
{
ans += z[i];
if(ans<0)
return true;
}
return false;
}
int main()
{
ios;
cin >> n >> m;
for (int i = 1; i <= n;i++)
{
cin >> x[i];
}
for (int i = 1; i <= n;i++)
{
y[i] = x[i] - x[i - 1];
}
for (int i = 1; i <= m;i++)
{
cin >> a[i] >> b[i] >> c[i];
}
int l = 1, r = m, s;
while (l<=r)
{
int mid = l + r >> 1;
if(check(mid))
{
r = mid - 1;
s = mid;
}
else
{
l = mid + 1;
}
}
if(check(l))
{
cout << -1 << "\n";
cout << l;
}
else
{
cout << 0;
}
return 0;
}
E
题解:后更