poj 3368 Frequent values 线段树 离散化
2016-02-12 19:59
423 查看
题目
题目链接:http://poj.org/problem?id=3368题目来源:群中有人问的。
简要题意:不递减序列,找到区间内数最多的出现次数。
题解
对数组进行离散化。找到每个区间左右多出来的那两段长度是多少。
对于中间的数可以搞个线段树或者用RMQ来弄出值在某区间内出现的最大值。
于是可以在O(nlogn)O(n\log n)时间内求解。
具体的做法我是用预处理向左向右第一个与a[i]a[i]不同的数的位置。
然后记数塞入一个线段树。
代码
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <queue> #include <string> #include <vector> #include <set> #include <map> #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define fi first #define se second using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;} // head const int N = 1E5+5;; int a ; int nxt ; int pre ; int cnt ; struct SegmentTree { #define lson (rt<<1) #define rson ((rt<<1)|1) #define MID ((L+R)>>1) #define lsonPara lson, L, MID #define rsonPara rson, MID+1, R int tree[N<<2]; void update(int rt) { tree[rt] = max(tree[lson], tree[rson]); } void build(int rt, int L, int R) { if (L == R) { tree[rt] = cnt[L]; } else { build(lsonPara); build(rsonPara); update(rt); } } int query(int rt, int L, int R, int l, int r) { if (r < L || l > R) return 0; if (l <= L && r >= R) return tree[rt]; return max(query(lsonPara, l, r), query(rsonPara, l, r)); } }; SegmentTree st; int main() { int n, q; while (scanf("%d%d", &n, &q) == 2) { int cur = 0, curv = 1e9; for (int i = 1; i <= n; i++) { scanf("%d", a+i); if (a[i] != curv) curv = a[i], cur++; a[i] = cur; cnt[cur]++; } for (int i = 1; i <= n; i++) { pre[i] = a[i]==a[i-1] ? pre[i-1] : i-1; } for (int i = n; i > 0; i--) { nxt[i] = a[i]==a[i+1] ? nxt[i+1] : i+1; } st.build(1, 1, cur); int ll, rr; while (q--) { scanf("%d%d", &ll, &rr); int lr = min(nxt[ll]-1, rr); int rl = max(pre[rr]+1, ll); int ans = max(lr - ll + 1, rr - rl + 1); if (lr+1 <= rl-1) ans = max(ans, st.query(1, 1, cur, a[lr+1], a[rl-1])); printf("%d\n", ans); } memset(cnt, 0, sizeof cnt); } return 0; }
相关文章推荐
- Android蓝牙技术Bluetooth初体验
- String ,StringBuilder, StringBuffer
- SWTableViewCell——一个和iOS 7的系统Mail类似,使用起来简单的UITableViewCell子类
- UESTC 250 windy数 (数位DP)
- iOS 【UIKit-转换坐标系(2)】
- NGUI 3.5教程(二)Label 标签 (Hello world)、多行文本
- [JSP] - frequently-used skills
- Key-Value Coding
- iOS 【UIKit-转换坐标系(1)】
- durpal8+Acquia Dev Desktop安装问题处理
- hdu1503Advanced Fruits【最长公共子序列】
- LeetCode 96 Unique Binary Search Trees不同的二叉搜索树的个数
- Building Maintainable Software-java篇之Write Simple Units of Code
- Educational Codeforces Round 7 A. Infinite Sequence 水题
- POJ 2623 Sequence Median(水~)
- 303. Range Sum Query - Immutable LeetCode
- UIView不接受触摸事件的三种情况:
- Educational Codeforces Round 7(D)构造(STL deque)
- Light OJ 1126 Building Twin Towers (DP)
- Building Maintainable Software-java篇之Write Short Units of Code