Codeforces Round #169 (Div. 2) C. Little Girl and Maximum Sum(线段树区间更新)
2013-03-01 17:20
393 查看
C. Little Girl and Maximum Sum
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
The little girl loves the problems on array queries very much.
One day she came across a rather well-known problem: you've got an array of n elements (the elements of the array are indexed starting from 1); also, there are q queries, each one is defined by a pair of integers li, ri (1 ≤ li ≤ ri ≤ n). You need to find for each query the sum of elements of the array with indexes from li to ri, inclusive.
The little girl found the problem rather boring. She decided to reorder the array elements before replying to the queries in a way that makes the sum of query replies maximum possible. Your task is to find the value of this maximum sum.
Input
The first line contains two space-separated integers n (1 ≤ n ≤ 2·105) and q (1 ≤ q ≤ 2·105) — the number of elements in the array and the number of queries, correspondingly.
The next line contains n space-separated integers ai (1 ≤ ai ≤ 2·105) — the array elements.
Each of the following q lines contains two space-separated integers li and ri (1 ≤ li ≤ ri ≤ n) — the i-th query.
Output
In a single line print a single integer — the maximum sum of query replies after the array elements are reordered.
Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.
Sample test(s)
Input
Output
Input
Output
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
The little girl loves the problems on array queries very much.
One day she came across a rather well-known problem: you've got an array of n elements (the elements of the array are indexed starting from 1); also, there are q queries, each one is defined by a pair of integers li, ri (1 ≤ li ≤ ri ≤ n). You need to find for each query the sum of elements of the array with indexes from li to ri, inclusive.
The little girl found the problem rather boring. She decided to reorder the array elements before replying to the queries in a way that makes the sum of query replies maximum possible. Your task is to find the value of this maximum sum.
Input
The first line contains two space-separated integers n (1 ≤ n ≤ 2·105) and q (1 ≤ q ≤ 2·105) — the number of elements in the array and the number of queries, correspondingly.
The next line contains n space-separated integers ai (1 ≤ ai ≤ 2·105) — the array elements.
Each of the following q lines contains two space-separated integers li and ri (1 ≤ li ≤ ri ≤ n) — the i-th query.
Output
In a single line print a single integer — the maximum sum of query replies after the array elements are reordered.
Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.
Sample test(s)
Input
3 3 5 3 2 1 2 2 3 1 3
Output
25
Input
5 3 5 2 4 1 3 1 5 2 3 2 3
Output
33 对每个数a[i],统计其被访问的次数cnt[i],将a和cnt分别从小到大排列,maxSum = a[0]*cnt[0]+a[1]*cnt[1]+……
#include <iostream> #include <string> #include <set> #include <map> #include <vector> #include <stack> #include <queue> #include <cmath> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define LL long long #define cti const int #define dg(i) cout << "*" << i << endl; cti MAXN = 200002; struct Node { int r, l; LL inc; //新增查询次数 LL cnt; //该区间被查询次数 }tree[MAXN<<2|1]; int lastNode; //记录最后一个结点的下标 LL a[MAXN]; bool tag[MAXN<<2|1]; //标记是否叶子 LL cnt[MAXN]; //记录叶子的访问次数 bool cmp (const LL& x, const LL& y) {return x > y;} void Build(int left, int right, int rt) { if(lastNode < rt) lastNode = rt; tree[rt].l = left; tree[rt].r = right; if(left == right) { tag[rt] = true; return ; } int mid = (left + right) >> 1; Build(left, mid, rt << 1); Build(mid + 1, right, rt << 1 | 1); } void Update(int from, int to, int rt) { if(from <= tree[rt].l && tree[rt].r <= to) { tree[rt].inc++; tree[rt].cnt++; return ; } if(tree[rt].inc) { tree[rt<<1].cnt += tree[rt].inc; tree[rt<<1|1].cnt += tree[rt].inc; tree[rt<<1].inc += tree[rt].inc; tree[rt<<1|1].inc += tree[rt].inc; tree[rt].inc = 0; } int mid = (tree[rt].l + tree[rt].r) >> 1; if(from <= mid) Update(from, to, rt << 1); if(to > mid) Update(from, to, rt << 1 | 1); } int main() { int n, q, from, to; while(scanf("%d %d", &n, &q) != EOF) { memset(tag, false, sizeof(tag)); for(int i = 0; i < n; i++) scanf("%I64d", &a[i]); for(int i = 1; i < (n<<2); i++) tree[i].cnt = tree[i].inc = 0; lastNode = 0; Build(1, n, 1); while(q--) { scanf("%d %d", &from, &to); Update(from, to, 1); } //此循环保证区间更新彻底往下传递 for(int i = 1, j = 0; i <= lastNode; i++) { if(tree[i].inc && (i<<1) < lastNode) { tree[i<<1].cnt += tree[i].inc; tree[i<<1|1].cnt += tree[i].inc; tree[i<<1].inc += tree[i].inc; tree[i<<1|1].inc += tree[i].inc; } if(tag[i]) //叶子 { cnt[j++] = tree[i].cnt; } } sort(a, a + n, cmp); sort(cnt, cnt + n, cmp); LL sum = 0; for(int i = 0; i < n; i++) sum += (cnt[i] * a[i]); printf("%I64d\n", sum); } return 0; }
相关文章推荐
- Codeforces 276C Little Girl and Maximum Sum(线段树的区间更新)
- Codeforces 276C Little Girl and Maximum Sum 线段树区间累加
- Educational Codeforces Round 37 (Rated for Div. 2) F. SUM and REPLACE(线段树,区间更新)
- code forces 276C Little Girl and Maximum Sum (线段树/技巧)
- Codeforces Round #169 (Div. 2)---C. Little Girl and Maximum Sum(简单贪心)
- Codeforces Round #442 (Div. 2)-E-Danil and a Part-time Job(DFS序+线段树区间更新)
- CF 276C - Little Girl and Maximum Sum 差分数列,线段树,splay
- CF EDU 37 F SUM and REPLACE 【线段树区间更新中的单点更新】 好题!
- [CF#365 (Div. 2) Mishka and Interesting sum] 线段树离线处理区间不同数
- Codeforces Round #169 (Div. 2)C. Little Girl and Maximum Sum(贪心/排序)
- HDU - 1823 Luck and Love(二维线段树、单点更新区间最值)
- 【HDU 4614】Vases and Flowers(线段树区间更新懒惰标记)
- CodeForces 276E - Little Girl and Problem on Trees 区间更新..N+1个线段树
- HDU 4614-Vases and Flowers(线段树区间更新)
- 【Codeforces Round 365 (Div 2)D】【离线询问 树状数组 前驱思想】Mishka and Interesting sum 区间内出现次数偶数的数的异或和
- Codeforces Round #223 (Div. 2) E. Sereja and Brackets 线段树区间合并
- HDU1823 Luck and Love (二维线段树 + 单点更新 + 区间查询)
- 【Codeforces Round 169 (Div 2) D】【简单数位贪心】Little Girl and Maximum XOR 区间选两数使得异或值尽可能大
- HDU-4614 Vases and Flowers 线段树区间更新
- 【Codeforces Round 370 (Div 2) E】【线段树 等比数列 区间合并】Memory and Casinos 赌场区间[l,r] l进r先出的概率