链接:https://dwacon5th-prelims.contest.atcoder.jp/tasks/dwacon5th_prelims_b
题意:
给定一个长度为n的序列,这n个数在序列中,一共会形成 n * (n + 1) / 2 个连续子序列,比如,1 2 3,可以形成:
{1}, {1,2},{1,2,3},{2,3},{3},这 6 个连续子序列,构成这个子序列的某一元素索引不同即可视为子序列不相同,比如:
1 2 1 2,可以形成,{1}, {1, 2}, {1, 2, 1}, {1, 2, 1, 2}, {2}, {2, 1}, {2, 1, 2}, {1}, {1, 2}, {2}。他们都被认为是不同的。那么这n个数所形成的这 n * (n + 1) / 2 个连续子序列,对应了 n * (n + 1) / 2 个序列元素和,比如 {1, 2, 1, 2} 的序列元素和就是1 + 2 + 1 + 2 = 6,从这n * (n + 1) / 2 个和中挑 k 个,打印这 k 个和 按位与的最大值。
思路:
这题我运用了vector,以及二进制枚举的操作,
首先,先将每个位置的数能形成的所有子序列的元素和,存进当前vector中,操作如下:
void Init() {
cin >> n >> k;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) {
ll sum = 0;
for(int j = i; j <= n; j++) {
sum += a[j];
vec.push_back(sum);
}
}
}
接下来我就进行二进制枚举每一位,从高位到低位枚举,看哪一位的1的个数不小于 k 个,那么,我挑选出来的这k个数,肯定是当前位是1的这些数的子集,那么我接下来只需要在当前位是1的这些数中继续按位枚举就行了,那么具体实现就是,再开一个名为 tmp 的 vector 去替换当前 vector,把当前位是1的数 push_back 进tmp,再 vec = tmp,进行替换。枚举到 bit 位的时候,由于已经确定当前的 vector 中的这些数,第 bit 位是1的数的个数大于等于k个,那就说明这一位一定参与最后形成最大值的按位与了,换句话说,这一位,一定是答案当前的一位,所以每次 ans += 1ll << bit位即可。
具体操作如下:
void solve() {
for(int bit = 59; bit >= 0; bit--) {
int t = 0;
int sz = vec.size();
for(int i = 0; i < sz; i++) {
ll dd = 1ll << bit;
if(vec[i] & dd) t++;
}
if(t < k) continue;
vector
tmp.clear();
for(int i = 0; i < sz; i++) {
ll dd = 1ll << bit;
if(vec[i] & dd) tmp.push_back(vec[i]);
}
vec = tmp;
ans += 1ll << bit;
}
}
我的AC代码:
#include
using namespace std;
typedef long long ll;
const int maxx = 1e6 + 7;
const int Inf = 1 << 30;
const ll INF = 1ll << 60;
#define mst(x) memset(x, 0, sizeof(x))
priority_queue
ll a[maxx];
vector
int n, k;
ll ans;
void Init() {
cin >> n >> k;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) {
ll sum = 0;
for(int j = i; j <= n; j++) {
sum += a[j];
vec.push_back(sum);
}
}
}
void solve() {
for(int bit = 59; bit >= 0; bit--) {
int t = 0;
int sz = vec.size();
for(int i = 0; i < sz; i++) {
ll dd = 1ll << bit;
if(vec[i] & dd) t++;
}
if(t < k) continue;
vector
tmp.clear();
for(int i = 0; i < sz; i++) {
ll dd = 1ll << bit;
if(vec[i] & dd) tmp.push_back(vec[i]);
}
vec = tmp;
ans += 1ll << bit;
}
}
int main() {
Init();
solve();
cout << ans << endl;
}