Solved | Pro.ID | Title | Ratio(Accepted / Submitted) |
---|---|---|---|
1001 | Salty Fish | 16.28%(7/43) | |
1002 | Nonsense Time | 7.88%(57/723) | |
1003 | Milk Candy | 12.90%(4/31) | |
1004 | Speed Dog | 26.97%(48/178) | |
1005 | Snowy Smile | 8.52%(225/2640) | |
1006 | Faraway | 27.92%(98/351) | |
1007 | Support or Not | 8.33%(3/36) | |
1008 | TDL | 27.63%(921/3333) | |
1009 | Three Investigators | 7.14%(1/14) | |
1010 | Ridiculous Netizens | 38.71%(24/62) | |
1011 | 11 Dimensions | 13.47%(64/475) | |
1012 | Stay Real | 45.04%(1044/2318) |
1008
考虑枚举 \(f(n, m) ) -n\) 的值 t,则 \(n = t ⊕ k\),\(O(tlog n)\) 检查这个 \(n\) 是否满足条件即可。
注意到 t 显然不会超过第 m 个与 n 互质的质数,而 n 最多只有 \(O(log log n) < m = 100\) 个
质数,根据质数密度可以得到 t 的一个比较松的上界 \(O(m log m)\)。
时间复杂度 \(O(m^2 log^2mlog n)\)。
#include
using namespace std;
typedef long long ll;
ll gcd(ll x, ll y) {
if(y == 0) return x;
return gcd(y, x % y);
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
ll m, k;
scanf("%lld%lld", &k, &m);
ll ans = -1;
for(ll i = max(1LL, k - 700); i <= k + 700; i++) {
ll tmp = (k ^ i) + i;
int cnt = 0;
if(gcd(i, tmp) != 1) continue;
for(ll j = i + 1; j <= tmp; j++) {
if(gcd(i, j) == 1) cnt++;
if(cnt > m) break;
}
if(cnt == m) {
ans = i;
break;
}
}
printf("%lld\n", ans);
}
return 0;
}
1012
小根堆中,每个点的权值总是不小于父亲节点的权值。所以无论怎么取,先拿走的数一定 不小于后面拿走的数。 此时双方的最优策略就是:贪心选择能取的数字之中最大的数。 时间复杂度 \(O(n log n)\)。
#include
using namespace std;
const int N = 100010;
typedef long long ll;
int n;
int T;
ll h[N],ans[2];
int main(){
scanf("%d",&T);
while(T--){
ans[0] = ans[1] = 0;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld",&h[i]);
sort(h+1,h+1+n);
int t = 0;
for(int i=n;i>=1;i--){
ans[t] += h[i];
t ^= 1;
}
printf("%lld %lld\n",ans[0],ans[1]);
}
return 0;
}