CodeForces 474EPillars(线断树区间最大)
来源:互联网 发布:java语言培训哪家好 编辑:程序博客网 时间:2024/06/05 11:55
题目链接
给出n个数字,和最小间隔d。从i能走到j的充要条件就是
|ai−aj|≥d ,求最长的路径长度并输出路径,有多解输出任意一组路径。
思路就是dp[i]表示以i结尾的最长路径长度,dp[i]<-{pre{dp[j]}里面满足条件且最长的长度} + 1,
这里查找的就可以是区间最大值的查找,因为要记录路径,所以里面还需要最大值对应的原序列中的位置。
const int maxn = 1e5 + 123;struct data { int len, loc; data() {} data(int len,int loc) : len(len), loc(loc) {} data operator + (const data& rhs) { return len >= rhs.len ? *this : rhs; }};struct node { int l, r; data v;}p[maxn<<4];void build(int rt, int l, int r) { p[rt] = node {l, r, data(0, 0)}; if (l == r) return ; int mid = (l + r) >> 1; build(lson, l, mid); build(rson, mid + 1, r);}inline void push_up(int rt) { p[rt].v = p[lson].v + p[rson].v;}void updata(int rt,int pos, data v) { if (p[rt].l == pos && p[rt].r == pos) { p[rt].v = p[rt].v + v; return ; } int mid = (p[rt].l + p[rt].r) >> 1; if (pos <= mid) updata(lson, pos, v); if (pos > mid) updata(rson, pos, v); push_up(rt);}data find(int rt,int L, int R) { if (L <= p[rt].l && p[rt].r <= R) return p[rt].v; int mid = (p[rt].l + p[rt].r) >> 1; if (R <= mid) return find(lson, L, R); if (L > mid) return find(rson, L, R); return find(lson, L, R) + find(rson, L, R);}LL h[maxn*5], a[maxn];int m;int nxt[maxn];int n, d;int main(int argc, const char * argv[]){ // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); // ios::sync_with_stdio(false); // cout.sync_with_stdio(false); // cin.sync_with_stdio(false); cin >> n >> d; Rep(i, 1, n) { scanf("%lld", &a[i]); h[++m] = a[i]; h[++m] = max(0LL, a[i] - d); h[++m] = a[i] + d; } sort(h + 1, h + 1 + m); m = unique(h + 1, h + 1 + m) - h - 1; build(1, 1, m); int res = 0; int o = 1; Rep(i, 1, n) { int l = lower_bound(h + 1, h + 1 + m, max(0LL, a[i] - d)) - h; int r = lower_bound(h + 1, h + 1 + m, a[i] + d) - h; data v = find(1, 1, l) + find(1, r, m); nxt[i] = v.loc; if (v.len + 1 > res) { res = v.len + 1; o = i; } int pos = lower_bound(h + 1, h + 1 + m, a[i]) - h; updata(1, pos, data(v.len + 1, i)); } vector<int> vec; printf("%d\n", res); for (int u = o;u ; u = nxt[u]) vec.push_back(u); for (int i = res - 1;i >= 0;--i) printf("%d ", vec[i]); puts(""); // showtime; return 0;}
0 0
- CodeForces 474EPillars(线断树区间最大)
- codeforces 366D 求1-n点最大区间长度 枚举区间左端+二分区间右端dfs判可行
- codeforces 474F 区间gcd + 离散化
- codeforces The Bakery(n个数划分k区间,权值为区间不同数,问总权值最大)
- codeforces 515e Drazil and Park 线段树、区间最大子段和
- codeforces 276D Little Girl and Maximum XOR(区间最大异或值--技巧)【模板】
- fjnu最大区间问题
- POJ2796 区间最大参考值
- 最大重叠区间大小
- 最大不重叠区间
- hdoj5280最大区间和
- 最大区间重叠.
- POJ3264 区间最大最小值
- 最大子区间和
- hoj5586 区间和最大
- 区间最大频率
- [区间DP]乘积最大
- 贪心:最大相交区间
- 设计模式——状态模式(C++)
- 某个服务的调用顺序
- UVAlive 6525 二分图匹配
- miniblink渲染架构重整
- 七天学会ASP.NET MVC (五)——Layout页面使用和用户角色管理
- CodeForces 474EPillars(线断树区间最大)
- 300. Longest Increasing Subsequence
- RC522读卡器 M1卡学习总结(二)
- NOIP2015普及组 金币
- JDBC--使用statement接口实现更新数据
- 简单算法之插入排序及其优化shell排序
- Go语言基础:并发
- makefile
- http://www.cnblogs.com/spring87/p/4496930.html