hdu 1806 Frequent values 线段树
2015-12-22 18:48
323 查看
题目链接
给一个非递减数列, n个数, m个询问, 每个询问给出区间[L, R], 求这个区间里面出现次数最多的数的次数。
非递减数列, 这是最关键的一个条件...
需要保存一个区间最左边的数, 最右边的数, 最长前缀, 最长后缀, 和这个区间里面次数最多的数的次数。
一个区间出现最多的数的次数, 应该是左区间和右区间里面取一个最大值。 如果左区间最右边的数和右区间最左边的数相同, 还需要判断这个数左右区间加起来的数量是否大于最大值。
合并的时候需要判断左区间最右边的数和右区间最左边的数是否相同, 具体看代码。
给一个非递减数列, n个数, m个询问, 每个询问给出区间[L, R], 求这个区间里面出现次数最多的数的次数。
非递减数列, 这是最关键的一个条件...
需要保存一个区间最左边的数, 最右边的数, 最长前缀, 最长后缀, 和这个区间里面次数最多的数的次数。
一个区间出现最多的数的次数, 应该是左区间和右区间里面取一个最大值。 如果左区间最右边的数和右区间最左边的数相同, 还需要判断这个数左右区间加起来的数量是否大于最大值。
合并的时候需要判断左区间最右边的数和右区间最左边的数是否相同, 具体看代码。
#include<bits/stdc++.h> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, a, n) for(int i = a; i<n; i++) #define ull unsigned long long typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 1e5+5; int lnum[maxn<<2], rnum[maxn<<2], maxx[maxn<<2], pre_max[maxn<<2], suf_max[maxn<<2]; void pushUp(int rt, int m) { maxx[rt] = max(maxx[rt<<1], maxx[rt<<1|1]); lnum[rt] = lnum[rt<<1]; rnum[rt] = rnum[rt<<1|1]; suf_max[rt] = suf_max[rt<<1|1]; if(suf_max[rt] == (m>>1)&&lnum[rt<<1|1] == rnum[rt<<1]) //如果左区间最右边的数和右区间最左边的数相等 suf_max[rt] += suf_max[rt<<1]; //并且左区间的后缀长度等于这段区间的长度 pre_max[rt] = pre_max[rt<<1]; if(pre_max[rt] == m-(m>>1) && rnum[rt<<1] == lnum[rt<<1|1]) pre_max[rt] += pre_max[rt<<1|1]; if(lnum[rt<<1|1] == rnum[rt<<1]) maxx[rt] = max(maxx[rt], pre_max[rt<<1|1]+suf_max[rt<<1]); } void build(int l, int r, int rt) { if(l == r) { scanf("%d", &lnum[rt]); rnum[rt] = lnum[rt]; maxx[rt] = pre_max[rt] = suf_max[rt] = 1; return ; } int m = l+r>>1; build(lson); build(rson); pushUp(rt, r-l+1); } int query(int L, int R, int l, int r, int rt) { if(L<=l&&R>=r) { return maxx[rt]; } int m = l+r>>1; if(R<=m) return query(L, R, lson); if(L>m) return query(L, R, rson); int tmp1 = query(L, m, lson); int tmp2 = query(m+1, R, rson); int tmp3 = 0; if(lnum[rt<<1|1] == rnum[rt<<1]) tmp3 = min(pre_max[rt<<1|1], R-m)+min(suf_max[rt<<1], m-L+1); return max(tmp1, max(tmp2, tmp3)); } int main() { int n, m; while(cin>>n&&n) { cin>>m; build(1, n, 1); while(m--) { int x, y; scanf("%d%d", &x, &y); printf("%d\n", query(x, y, 1, n, 1)); } } return 0; }
相关文章推荐
- [Android UI界面]RelativeLayou布局
- Builder模式
- (转)Android属性设置android:noHistory="true"
- UITableView的关键内容
- 传入16进制颜色获得色值(UIColor)
- mysql执行大文件报错:Error Code: 2013. Lost connection to MySQL server during query
- 解决CAS单点登录出现PKIX path building failed的问题
- Java 字符串(String, StringBuffer, StringBuilder,StringTonkenizer)
- UI学习第02天
- Spark调度系列-----5.Spark task和Stage的跳过执行(ui显示task和stage skipped)
- Libgdx学习笔记:UI之技能冷却按钮(新版)
- FMDB使用Queue:FMDatabaseQueue
- 示例详解:UIScrollview 与 Autolayout 的那点事
- UITableView索引
- 循环结构中break、continue、return的区别
- UIPageControl
- dispatch_async 与 dispatch_get_global_queue 的使用方法
- UIView
- 在4.0下针对检测到有潜在危险的 Request.Form 值的方法
- mybatis 显示参数${} #{},${}适用场景 miniui sortField sortOrder