CC Sereja and Ballons (主席树)
来源:互联网 发布:网络商务模式 编辑:程序博客网 时间:2024/05/20 21:19
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
题意:有n个盒子,每个盒子有若干个气球,每次操作可以拿走某个盒子的一个气球,然后 给出一些区间,问每次操作后有多少个区间的盒子全为空。
http://www.codechef.com/AUG13/problems/SEABAL
做法:用链表维护一下当前位置前一个非0位置,下一个非0位置。
如果当前位置为k,前一个非0位置为l,下一个非0位置为r。
那么当前位置减为了0,此时增加的区间应该是左端点在(l,k] ,右端点在[k,r)。
那么接下来就是查询一下有多少个区间满足这个条件。
用主席树维护以每个位置为区间右端点的左端点位置。
#include <iostream>#include <cstdio>#include <set>#include <vector>#include <cstring>#include <algorithm>#define mem(a,b) memset (a , b , sizeof(a))using namespace std;const int N = 100005;const int M = 30000005;struct Node { int l , r; void input () { scanf ("%d %d" , &l , &r); } bool operator < (const Node &n) const { return r < n.r; }}que[N];int n , m , q , a[N]; int T[M] , lson[M] , rson[M] , sum[M] , tot = 0;int l[N] , r[N];int bulid (int l , int r) { int root = ++ tot; sum[root] = 0; if (l != r) { int m = (l + r) >> 1; lson[root] = bulid (l , m); rson[root] = bulid (m + 1 , r); } return root;}int update (int root , int l , int r , int pos) { int newroot = ++ tot; sum[newroot] = sum[root] + 1; if (l != r) { int m = (l + r) >> 1; if (pos <= m) { lson[newroot] = update (lson[root] , l , m , pos); rson[newroot] = rson[root]; } else { rson[newroot] = update (rson[root] , m + 1 , r , pos); lson[newroot] = lson[root]; } } //cout << sum[newroot] << " " << sum[lson[newroot]] << " " << sum[rson[newroot]] << endl;; return newroot;}int query (int root , int L , int R , int l , int r) { if (L == l && R == r) { return sum[root]; } int m = (L + R) >> 1; if (r <= m) return query (lson[root] , L , m , l , r); else if (l > m) return query (rson[root] , m + 1 , R , l , r); else return query (lson[root] , L , m , l , m) + query (rson[root] , m + 1 , R , m + 1 , r);}void out (int root , int l , int r) { cout << l << " " << r << " " << sum[root] << endl; if (l != r) { int m = (l + r) >> 1; out (lson[root] , l , m); out (rson[root] , m + 1 , r); }}int main () { // freopen ("input.txt" , "r" , stdin); // freopen ("output.txt" , "w" , stdout); scanf ("%d %d" , &n , &m); l[0] = 0; r[n + 1] = n + 1; for (int i = 1 ; i <= n ; i ++) { scanf ("%d" , &a[i]); l[i] = i - 1; r[i] = i + 1; } for (int i = 0 ; i < m ; i ++) { que[i].input(); } sort (que , que + m); T[0] = bulid (1 , n); for (int i = 1 , j = 0 ; i <= n ; i ++) { T[i] = T[i - 1]; while (j < m && que[j].r == i) { T[i] = update (T[i] , 1 , n , que[j].l); j ++; } // cout << "root : " << i << endl; // out (T[i] , 1 , n); } scanf ("%d" , &q); int ans = 0; while (q --) { int k; scanf ("%d" , &k); k += ans; //cout << k << endl; a[k] --; if (a[k] == 0) { int L = l[k] , R = r[k]; int ret = query (T[R - 1] , 1 , n , L + 1 , k) - query (T[k - 1] , 1 , n , L + 1 , k); ans += ret; // cout << "ret :" << ret << endl; if (r[k] <= n) l[r[k]] = l[k]; if (l[k] >= 1) r[l[k]] = r[k]; } printf ("%d\n" , ans); } return 0;}
- CC Sereja and Ballons (主席树)
- CC Sereja and Ballons (主席树)
- Sereja and Ballons CC SEABAL
- CF380C Sereja and Brackets [想法+线段树]
- C. Sereja and Brackets----线段树
- 划分树and主席树
- B. Sereja and Array
- Sereja and Bottles
- Sereja and Bottles
- A. Sereja and Bottles
- B. Sereja and Suffixes
- CF380A Sereja and Prefixes
- A. Sereja and Dima
- Sereja and Stairs
- B. Sereja and Stairs
- Sereja and Stairs
- Sereja and Dima
- B. Sereja and Contests
- TeX括号
- Multiset多重集合容器
- 手机网站调试神器之chrome控制台
- 开发总结
- 【TCP/IP详解】第13章 IGMP: Internet组管理协议
- CC Sereja and Ballons (主席树)
- 【TCP/IP详解】第14章 DNS:域名系统
- ubuntu tomcat7.0 配置
- JAVA 双向SSL,SOCKET客户端/服务端
- 黑马程序员_09 Io流
- deque的简介
- 【TCP/IP详解】第15章 TFTP:简单文件传送协议
- C#线程之间操作无效|不允许访问控件(c# 线程间操作无效: 从不是创建控件“”的线程访问它)
- VLC简介及使用说明、编译