HDU 5654 xiaoxin and his watermelon candy
来源:互联网 发布:java android api 编辑:程序博客网 时间:2024/05/29 04:32
题意:
给定一个数组,询问区间内有多少个满足要求的不同的三元组,三元组要求:
j=i+1,k=j+1 ,ai≤aj≤ak
思路:
很裸的主席树求区间内不同的数的个数,这类问题的方法就是,用数组
pre[i] 表示前一个与a[i] 相同的数的位置,以pre 数组为关键字,对于询问[L,R] ,再用主席树去在区间内查询有多少个数 小于L ,因为pre[i]≤L−1 说明这个数在[L,R] 内是不会被重复计数的!
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <map>#include <cmath>#include <algorithm>#include <vector>using namespace std;#define N 202000#define M 400030#define mod 1000000007#define LL long longint n, q;int a[N];struct node { int x, y, z, p; node() {} node(int x, int y, int z, int p):x(x), y(y), z(z), p(p) {} bool operator < (const node &b) const { if(x != b.x) return x < b.x; if(y != b.y) return y < b.y; if(z != b.z) return z < b.z; return p < b.p; } bool operator == (const node &b) const { return x == b.x && y == b.y && z == b.z; }}b[N];int pre[N];int rt[N];int s[N*40], ch[N*40][2], sz;#define md (ll + rr >> 1)int update(int i, int l, int r, int v, int ll, int rr) { int k = ++sz; if(k == N * 40 - 1) { vector<int> g; g[1] = -1; } ch[k][0] = ch[i][0]; ch[k][1] = ch[i][1]; s[k] = s[i]; if(ll == l && rr == r) { s[k] += v; return k; } if(r <= md) ch[k][0] = update(ch[i][0], l, r, v, ll, md); else if(l > md) { ch[k][1] = update(ch[i][1], l, r, v, md + 1, rr); } else { ch[k][0] = update(ch[i][0], l, md, v, ll, md); ch[k][1] = update(ch[i][1], md + 1, r, v, md + 1, rr); } return k;}int query(int i, int o, int x, int ll, int rr) { int ret = s[i] - s[o]; if(ll == rr) return ret; if(x <= md) ret += query(ch[i][0], ch[o][0], x, ll, md); else ret += query(ch[i][1], ch[o][1], x, md + 1, rr); return ret;}int main() { int cas; scanf("%d", &cas); while(cas--) { sz = 0; scanf("%d", &n); for(int i = 1; i <= n; ++i) { scanf("%d", &a[i]); } int cnt = 0; for(int i = 1; i <= n - 2; ++i) { if(a[i] <= a[i+1] && a[i+1] <= a[i+2]) { b[++cnt] = node(a[i], a[i+1], a[i+2], i); } } for(int i = 1; i <= n; ++i) pre[i] = n + 1; sort(b + 1, b + cnt + 1); for(int i = 1; i <= cnt; ++i) { int j = i; while(j <= cnt && b[j] == b[i]) ++j; --j; int x = -1; for(int k = i; k <= j; ++k) { if(x == -1) pre[b[k].p] = 0; else pre[b[k].p] = x; x = b[k].p; } i = j; } for(int i = 1; i <= n; ++i) { rt[i] = rt[i-1]; if(pre[i] != n + 1) { rt[i] = update(rt[i], pre[i] + 1, i, 1, 1, n); } } scanf("%d", &q); while(q--) { int l, r; scanf("%d%d", &l, &r); r -= 2; if(l > r) { puts("0"); continue; } printf("%d\n", query(rt[r], rt[l-1], l, 1, n)); } } return 0;}
0 0
- HDU 5654 xiaoxin and his watermelon candy
- HDU 5654 xiaoxin and his watermelon candy
- HDU 5654 xiaoxin and his watermelon candy 归并树
- dp hdu5653 xiaoxin and his watermelon candy
- HDU5654 xiaoxin and his watermelon candy 莫队
- 【没A】【HDU 5654】 xiaoxin and his watermelon candy|主席树
- 线段树+离线 hdu5654 xiaoxin and his watermelon candy
- 【HDOJ 5654】 xiaoxin and his watermelon candy(离线+树状数组)
- [hdu5654 xiaoxin and his watermelon candy]区间内不同数的个数
- 【HDU5654 BestCoder Round 77 (div1) D】【前驱位置思想 排序 树状数组】xiaoxin and his watermelon candy 区间内多少个不同连续单升三元
- HDU - 5410 CRB and His Birthday
- HDU 5410 CRB and His Birthday
- hdu acm 5410 CRB and His Birthday
- HDU 5410 CRB and His Birthday
- CRB and His Birthday(HDU-5410)
- hdu 6222 Heron and His Triangle
- HDU 5410 CRB and His Birthday
- HDU 5410 CRB and His Birthday(DP)
- iOS离屏绘制的性能和机制分析
- 编写将一个包含有20个数据的数组M分成两个数组,正整数数组P和负数数组N ,分别把这两个数组中的数据的个数显示出来
- CSS3学习笔记(二)2015-12-9【从新浪云搬运】
- 最火爆的开源流式系统Storm vs 新星Samza
- binder第二课
- HDU 5654 xiaoxin and his watermelon candy
- 关于大型网站技术演进的思考(十四)--网站静态化处理—前后端分离—上(6)
- 挖掘DBLP作者合作关系,FP-Growth算法实践(5):挖掘研究者合作关系
- 文档词频分析小工具
- 关于大型网站技术演进的思考(十三)--网站静态化处理—CSI(5)
- UVa 340 - Master-Mind Hints
- 笔试练习二
- 有关Mac版本AS类里面无法编写代码的问题
- MYSQL中group_concat有长度限制!默认1024