UPC 2224 Boring Counting ★(山东省第四届ACM程序设计竞赛 tag:线段树)
2013-06-18 12:46
501 查看
[题意]给定一个长度为N的数列,M个询问区间[L,R]内大于等于A小于等于B的数的个数.
[题目链接]http://acm.upc.edu.cn/problem.php?id=2224
省赛的时候脑抽想了10min没想出来就看别的题去了= =,赛后又想了10min想出来了并且1Y。。。真嫌弃自己= =。。。
[分析]如果做过询问区间[L,R]内小于H的个数的那道线段树题(HDU 4417 2012年杭州赛区网络赛)那么这题就好想了。那在这里再说一下做法:{将所有的询问离线读入之后,按H从小到大排序。对于所有的区间数也按从小到大排序,然后根据查询的H,将比H小的点加入到线段树,然后就是一个区间和}。
那么这题也就简单了。。。按上面方法分别求出区间[L,R]内大于等于A的个数num1和小于等于B的个数num2,然后res = num1 + num2 - [L,R].
[题目链接]http://acm.upc.edu.cn/problem.php?id=2224
省赛的时候脑抽想了10min没想出来就看别的题去了= =,赛后又想了10min想出来了并且1Y。。。真嫌弃自己= =。。。
[分析]如果做过询问区间[L,R]内小于H的个数的那道线段树题(HDU 4417 2012年杭州赛区网络赛)那么这题就好想了。那在这里再说一下做法:{将所有的询问离线读入之后,按H从小到大排序。对于所有的区间数也按从小到大排序,然后根据查询的H,将比H小的点加入到线段树,然后就是一个区间和}。
那么这题也就简单了。。。按上面方法分别求出区间[L,R]内大于等于A的个数num1和小于等于B的个数num2,然后res = num1 + num2 - [L,R].
#include #include #include #include #include #include #include #include #include #include #include #include #define MID(x,y) ((x+y)>>1) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int MAXN = 50002; struct Segment_Tree{ int sum[MAXN<<2]; void build(){ mem(sum, 0); } void pushup(int rt){ sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void update(int p, int v, int l, int r, int rt){ if (l == r){ sum[rt] = v; return ; } int mid = MID(l, r); if (p <= mid) update(p, v, l, mid, rt<<1); else update(p, v, mid+1, r, rt<<1|1); pushup(rt); }; int query(int l, int r, int L, int R, int rt){ if (l <= L && R <= r){ return sum[rt]; } int mid = MID(L,R); int ans = 0; if (l <= mid) ans += query(l, r, L, mid, rt<<1); if (mid < r) ans += query(l, r, mid+1, R, rt<<1|1); return ans; } }S; struct num{ int value; int position; }A[MAXN]; struct queries{ int l, r; int a, b; int num_greater_a; int num_less_b; int res; int id; }q[MAXN]; bool cmp(num n1, num n2){ return n1.value < n2.value; } bool cmp1(queries n1, queries n2){ return n1.a > n2.a; } bool cmp2(queries n1, queries n2){ return n1.b < n2.b; } bool cmpid(queries n1, queries n2){ return n1.id < n2.id; } int main(){ int t; scanf("%d", &t); for (int o = 1; o <= t; o ++){ int n, m; scanf("%d %d", &n, &m); for (int i = 0; i < n; i ++){ scanf("%d", &A[i].value); A[i].position = i + 1; } for (int i = 0; i < m; i ++){ scanf("%d %d %d %d", &q[i].l, &q[i].r, &q[i].a, &q[i].b); q[i].id = i; } sort(A, A+n, cmp); sort(q, q+m, cmp1); int j = n - 1; S.build(); for (int i = 0; i < m; i ++){ while(j >= 0 && A[j].value >= q[i].a){ S.update(A[j].position, 1, 1, n, 1); j --; } q[i].num_greater_a = S.query(q[i].l, q[i].r, 1, n, 1); } sort(q, q+m, cmp2); j = 0; S.build(); for (int i = 0; i < m; i ++){ while(j < n && A[j].value <= q[i].b){ S.update(A[j].position, 1, 1, n, 1); j ++; } q[i].num_less_b = S.query(q[i].l, q[i].r, 1, n, 1); q[i].res = q[i].num_greater_a + q[i].num_less_b - (q[i].r - q[i].l + 1); } sort(q, q+m, cmpid); printf("Case #%d:\n", o); for (int i = 0; i < m; i ++){ printf("%d\n", q[i].res); } } return 0; } /************************************************************** Problem: 2224 User: AbandonZHANG Language: C++ Result: Accepted Time:1052 ms Memory:4016 kb ****************************************************************/
相关文章推荐
- UPC 2224 Boring Counting ★(山东省第四届ACM程序设计竞赛 tag:线段树)
- UPC 2224 / “浪潮杯”山东省第四届ACM大学生程序设计竞赛 1008 Boring Counting 主席树
- UPC 2224 Boring Counting (离线线段树,统计区间[l,r]之间大小在[A,B]中的数的个数)
- 山东省第四届ACM程序设计竞赛A题:Rescue The Princess(数学+计算几何)
- 第四届 山东省ACM SDUT 2607 Mountain Subsequences(LIS+哈希 OR 线段树 待解决)
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛 E: 简单的RMQ【线段树】
- 山东省第四届ACM程序设计竞赛A题:Rescue The Princess(向量旋转)
- 【山东省第四届ACM省赛】Boring Counting(二分+划分树)
- 山东省第四届ACM大学生程序设计竞赛-Boring Counting(划分树-二分查找)
- UPC:2224 Boring Counting(二分+划分树)
- 山东省第四届ACM大学生程序设计竞赛 Boring Counting 划分树
- 山东省第四届ACM省赛题——Alice and Bob(二进制)
- 山东省第四届ACM大学生程序设计竞赛 Thrall’s Dream(单源强连通分量)
- POJ 3468 A Simple Problem with Integers(线段树 + Lazy Tag(延迟更新))
- 第四届“图灵杯”NEUQ-ACM程序设计竞赛 A: 谷神的游戏【思维+组合数学】
- **第四届“图灵杯”NEUQ-ACM程序设计竞赛(个人赛)C粉丝与汉诺塔
- 2013年山东省第四届ACM大学生程序设计竞赛:Rescue The Princess
- sdut Mountain Subsequences 2013年山东省第四届ACM大学生程序设计竞赛
- 山东省第四届ACM Mountain Subsequences 解题报告
- 第四届 山东省ACM The number of steps (概率dp 待整理)