AtCoder Regular Contest 075 2017年6月4日 C、D、E题解
http://arc075.contest.atcoder.jp/assignments
昨晚做的atcoder,今天写个简单题解。
F题不会做,800point的,就跪了,要等zk大佬来做。zk能做2400的
C题、我看到数据范围就直接100^3的背包,但是如果数据大点还是可以做的,贪心,首先全部值加起来,如果是%10==0的话,就需要去搭错一题,一题最少分的,而且%10 != 0的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; const int maxn = 1e2 + 20; int dp[maxn * maxn]; void work() { dp[0] = true; int n; cin >> n; for (int i = 1; i <= n; ++i) { int val; cin >> val; for (int i = 10000; i >= val; --i) { if (dp[i - val]) dp[i] = true; } } int ans = 0; for (int i = 10000; i >= 0; --i) { if (dp[i]) { ans = max(ans, i % 10 == 0 ? 0 : i); } } printf("%d\n", ans); } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }
D题、推公式二分,
设x[i]表示在h[i]个位置投放的数量,sum表示x[i]的总和,那么sum就是答案,
对于第h[i]个,需要它死亡,条件是,h[i] - (x[i] * A + (sum - x[i]) * B) <= 0
二分答案sum,然后需要判断n个h[i]都要死亡,每个h[i]死亡,需要的x[i]继续二分,判断即可。sum是满足单调的很容易看出来,
x[i]也满足单调因为A > B,可以化简公式看看,复杂度O(n * log * log),注意不要爆LL
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; LL n, a, b; LL all; int hi[1000000 + 20]; LL isok(int index, LL sum) { LL be = 0, en = sum; while (be <= en) { LL mid = (be + en) >> 1; if (a * mid + (sum - mid) * b >= hi[index]) en = mid - 1; else be = mid + 1; } return be; } bool check(LL sum) { LL need = 0; for (int i = 1; i <= n; ++i) { need += isok(i, sum); if (need > sum) return false; } return true; } void work() { cin >> n >> a >> b; for (int i = 1; i <= n; ++i) { cin >> hi[i]; all += hi[i]; } if (n == 1) { cout << (hi[1] + a - 1) / a << endl; return; } LL be = 0, en = 1e9; while (be <= en) { LL mid = (be + en) >> 1; if (check(mid)) en = mid - 1; else be = mid + 1; } cout << be << endl; } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }
E题、化简公式 + BIT
设sum[i]表示前缀和,区间[L, R]满足条件,等价于sum[R] - sum[L - 1] >= (R- L + 1) * k
等价于sum[R] - R * k >= sum[L -1] - (L - 1) * k
相当于找前面有多少个数字比当前数字小,离散化 + bit即可。
复杂度 nlogn
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; const int maxn = 2e5 + 20; LL sum[maxn]; int c[maxn]; int n, k; int lowbit(int x) { return x & (-x); } void upDate(int pos, int val) { while (pos <= n) { c[pos] += val; pos += lowbit(pos); } } int ask(int pos) { int ans = 0; while (pos) { ans += c[pos]; pos -= lowbit(pos); } return ans; } LL vc[maxn], lenvc; void work() { scanf("%d%d", &n, &k); for (int i = 1; i <= n; ++i) { int val; scanf("%d", &val); sum[i] = sum[i - 1] + val; } for (int i = 1; i <= n; ++i) { sum[i] -= 1LL * i * k; vc[++lenvc] = sum[i]; // cout << sum[i] << " "; } // cout << endl; sort(vc + 1, vc + 1 + lenvc); LL ans = 0; for (int i = 1; i <= n; ++i) { int pos = lower_bound(vc + 1, vc + 1 + lenvc, sum[i]) - vc; if (sum[i] >= 0) { ans++; } ans += ask(pos); upDate(pos, 1); } cout << ans << endl; } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }
posted on 2017-06-04 10:42 stupid_one 阅读(182) 评论(0) 编辑 收藏 举报