Codeforces 629 D Finals in arithmetic(最大上升子序列和,O(nlogn)、线段树/树状数组)
来源:互联网 发布:模具分析软件 编辑:程序博客网 时间:2024/06/09 23:00
题目链接:
Codeforces 629 D Finals in arithmetic
题意:
已知
- 编号大的蛋糕只能放在编号比它小的蛋糕上面或者桌子上
- 上面蛋糕的体积必须严格大于下面蛋糕的体积
求最终堆成的蛋糕的最大体积?
数据范围:
分析:
实际上就是求最大上升子序列和。
普通的dp方法是:
时间复杂度是
考虑将寻找
对于
时间复杂度:
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <climits>#include <cmath>#include <ctime>#include <cassert>#define lson(x) (x << 1) #define rson(x) ((x << 1) | 1)#define IOS ios_base::sync_with_stdio(0); cin.tie(0);using namespace std;typedef long long ll;const int MAX_N = 100010;int n;ll data[MAX_N], extra[MAX_N];struct SegmentTree { int left, right; ll value, lazy;}segtree[MAX_N << 2];void build(int left, int right, int cur){ segtree[cur].left = left, segtree[cur].right = right, segtree[cur].value = 0; if(left == right) return ; int mid = (left + right) >> 1; build(left, mid, lson(cur)); build(mid + 1, right, rson(cur));}ll query(int a, int b, int cur){ if(a > b) return 0; int left = segtree[cur].left, right = segtree[cur].right; if(left == a && right == b) { return segtree[cur].value; } int mid = (left + right) >> 1; if (b <= mid) return query(a, b, lson(cur)); else if (a > mid) return query(a, b, rson(cur)); else return max(query(a, mid, lson(cur)), query(mid + 1, b, rson(cur)));}void update(int goal, ll value, int cur){ int left = segtree[cur].left, right = segtree[cur].right; if(left == right) { segtree[cur].value = max(segtree[cur].value, value); return ; } int mid = (left + right) >> 1; if(goal <= mid) update(goal, value, lson(cur)); else update(goal, value, rson(cur)); segtree[cur].value = max(segtree[lson(cur)].value, segtree[rson(cur)].value);}int main(){ while (~scanf("%d", &n)) { for (int i = 1; i <= n; ++i) { ll r, h; scanf("%I64d%I64d", &r, &h); data[i] = r * r * h; extra[i] = data[i]; } sort(extra + 1, extra + n + 1); int m = unique(extra + 1, extra + n + 1) - extra - 1; build(1, m, 1); ll ans = 0; for (int i = 1; i <= n; ++i) { int pos = lower_bound(extra + 1, extra + m + 1, data[i]) - extra; ll tmp = data[i] + query(1, pos - 1, 1); ans = max(ans, tmp); update(pos, tmp, 1); //printf("pos = %d ans = %I64d\n", pos, ans); } printf("%.10lf\n", ans * acos(-1.0)); } return 0;}
好像用树状数组写更方便点。。。。。。
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <climits>#include <cmath>#include <ctime>#include <cassert>#define IOS ios_base::sync_with_stdio(0); cin.tie(0);using namespace std;typedef long long ll;const int MAX_N = 100010;int n;ll data[MAX_N], C[MAX_N], extra[MAX_N];ll GetMax(int x){ ll res = 0; while (x) { res = max(res, C[x]); x -= (x & (-x)); } return res;}ll update(int x, ll value){ while(x <= n) { C[x] = max(C[x], value); x += (x & (-x)); }}int main(){ while (~scanf("%d", &n)) { for(int i = 1; i <= n; ++i) { ll r, h; scanf("%I64d%I64d", &r, &h); extra[i] = data[i] = r * r * h; } sort(extra + 1, extra + n + 1); int m = unique(extra + 1, extra + n + 1) - extra - 1; memset(C, 0, sizeof(C)); ll ans = 0; for (int i = 1; i <= n; ++i) { int pos = lower_bound(extra + 1, extra + m + 1, data[i]) - extra; ll tmp = GetMax(pos - 1); ans = max(ans, tmp + data[i]); update(pos, tmp + data[i]); } printf("%.10lf\n", ans * acos(-1.0)); } return 0;}
0 0
- Codeforces 629 D Finals in arithmetic(最大上升子序列和,O(nlogn)、线段树/树状数组)
- Codeforces 625 D Finals in arithmetic
- Codeforces 625D ---- Finals in arithmetic
- Codeforces 625D Finals in arithmetic(构造)
- 最长上升子序列O(nlogn)算法
- 最长上升(下降)子序列 O(nlogn)
- 最长上升子序列 O(nlogn)
- 最长上升子序列O(nlogn)算法
- 最长上升子序列O(NlogN)算法
- 最长严格上升子序列O(nlogn)
- 最长上升子序列O(nlogn)
- 最长上升子序列O(nlogn)
- 最长上升子序列 O(nlogn)
- 【模板】最长上升子序列 O(nlogn)
- 最大上升子序列(从前往后) nlogn 和最大上升序列(从后往前)
- 用O(nlogn)的算法实现最大上升子序列(LIS)输出.
- Codeforces #342 D. Finals in arithmetic 模拟 构造
- CodeForces 625 D.Finals in arithmetic(构造)
- Activity进入退出动画总结
- Github 教程
- windows 环境下Eclipse开发MapReduce环境设置
- Spring Aop详尽教程
- Android之AsyncTask异步任务——防止内存泄露
- Codeforces 629 D Finals in arithmetic(最大上升子序列和,O(nlogn)、线段树/树状数组)
- 在WPF的TreeView中实现右键选定
- UVa 11478 Halum BellmanFord判负权环
- 欢迎使用CSDN-markdown编辑器
- nyoj 1070 诡异的电梯【Ⅰ】 动态规划
- 说起Android的Binder,我们都能说些什么?
- 新空间RecycleView复习
- ViewPager嵌套Fragment实现item实时更新的两种方式
- 字符串反转(reverse函数)