我做这场比赛的时候晕得要死。做这三道题做太久了,rating涨不起来啊!
如果愿意的话你可以看做是膜2意义下的运算,写快速幂等各种膜运算。只不过对手速有考验。
我题意差点理解不了了。这里讲一下题意:
给你\(m\)条棍子,编号从\(1\)到\(m\),有\(n\)个位置的棍子断了。你有无限长的修改带,求你用\(k\)次机会修补棍子,所用修改带的最小长度。允许修补到没断的棍子,允许修改区间重叠。
比赛的时候硬死想不出来,其实挺sb的:
我们贪心地覆盖前\(n-k\)短的区间,剩下的区间直接一个点覆盖即可。
没错,就这么sb且贪心。
我是想不出来。
题意当然是看不懂啦!我们打表看看有没有规律。
打表出来的规律就是:如果数字满足\(2^k-1\),那答案是个奇怪的没有规律的答案,否则答案是比它大的第一个\(2^k-1\)。
这里就有两种做法:
/*************************************************************************
@Author: Garen
@Created Time : Thu 07 Feb 2019 09:15:33 PM CST
@File Name: A.cpp
@Description:
************************************************************************/
#include<bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
#define ll long long
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll gcd(ll x, ll y) {
return y == 0 ? x : gcd(y, x % y);
}
ll f(ll a) {
ll res = -INF, idx = -1;
for(ll b = 1; b < a; b++) {
ll temp = gcd(a ^ b, a & b);
//res = std::max(res, gcd(a ^ b, a & b));
if(temp > res) {
res = temp; idx = b;
}
}
cout << idx << endl;
return res;
}
bool check(ll a) {
ll i = 1;
while(i <= a) {
if(i == a) return true;
i = (i << 1 | 1);
}
return false;
}
void baoli(ll a) {
ll bound = sqrt(a);
ll ans = -INF;
for(ll i = 1; i <= bound; i++) {
if(a % i == 0) {
if(i != 1) ans = std::max(ans, gcd(a ^ i, a & i));
if(a / i != i) {
ll j = a / i;
if(j != a) ans = std::max(ans, gcd(a ^ j, a & j));
}
}
}
if(ans == -INF) ans = 1;
cout << ans << endl;
}
int main() {
ll q; cin >> q;
while(q--) {
ll a; cin >> a;
if(check(a)) {
baoli(a);
} else {
ll i = 1;
while(i <= a) i = (i << 1 | 1);
cout << i << endl;
}
}
/*
for(ll a = 1; a <= 10000; a++) {
cout << "f(" << a << ") = ";
if(check(a)) {
baoli(a);
} else {
ll i = 1;
while(i <= a) i = (i << 1 | 1);
cout << i << endl;
}
}
*/
return 0;
}
这里立一个flag。听说不难的样子。
原文:https://www.cnblogs.com/Garen-Wang/p/10403679.html