hlgChocolate Auction【并查集】
来源:互联网 发布:阿里云dns怎么样 编辑:程序博客网 时间:2024/05/21 11:28
大意:
给你一个区间大小为100000000 然后每次查询一个区间之内有多少值未被标记并且把该区间之内的所有的未被标记的全部标记
查询次数为100000
分析:
这个题给我的第一感觉就是线段树但是线段树10^7的话开不下啊
然后并查集再一次发挥了它无穷大的力量
我们对于每个查询的区间
把其中所有的值都指向他能指向的最远的值
那么我们总的查找次数就可以控制在10^7之内
完美解决问题
说的有点抽象
用代码模拟一下你就会发现这个方法有多么的机智
我准备用线段树做一下
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int maxn = 10000005; 7 8 int fa[maxn]; 9 10 int find(int x) {11 if(x == fa[x]) return x;12 return fa[x] = find(fa[x]);13 }14 15 int main() {16 int t;17 int n, m;18 int a, b;19 scanf("%d",&t);20 while(t--) {21 scanf("%d %d",&n, &m);22 for(int i = 0; i <= n + 3; i++) {23 fa[i] = i;24 }25 for(int i = 1; i <= m; i++) {26 scanf("%d %d",&a, &b);27 int p = find(a);28 int cnt = 0;29 while(p <= b) {30 cnt ++;31 fa[find(p)] = find(p + 1);32 p = find(p + 1);33 }34 printf("%d\n",cnt);35 }36 }37 return 0;38 }
线段树代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int maxn = 10000005; 7 8 struct Node { 9 int left, right;10 int tot; 11 int mark;12 }tree[maxn << 2];13 14 int creat(int root, int left, int right) {15 tree[root].mark = 0;16 tree[root].left = left;17 tree[root].right = right;18 if(left == right) return tree[root].tot = 1;19 int a, b, mid = (left + right) >> 1;20 a = creat(root << 1, left, mid);21 b = creat(root << 1 | 1, mid + 1, right);22 return tree[root].tot = a + b;23 }24 25 void update_mark(int root) {26 if(tree[root].mark) {27 tree[root].tot = 0;28 if(tree[root].left != tree[root].right) {29 tree[root<<1].mark = tree[root<<1|1].mark = tree[root].mark;30 }31 tree[root].mark = 0;32 }33 }34 35 int update(int root, int left, int right) {36 update_mark(root);37 38 if(tree[root].left > right || tree[root].right < left) {39 return tree[root].tot;40 }41 42 if(left <= tree[root].left && tree[root].right <= right) {43 tree[root].mark = 1;44 return tree[root].tot = 0;45 }46 47 int a, b;48 49 a = update(root << 1, left, right);50 b = update(root << 1 | 1, left, right);51 return tree[root].tot = a + b;52 }53 54 55 int cal(int root, int left, int right) {56 update_mark(root);57 58 if(tree[root].left > right || tree[root].right < left) {59 return 0;60 }61 62 if(tree[root].left >= left && tree[root].right <= right) {63 return tree[root].tot;64 }65 int a, b;66 a = cal(root << 1, left, right);67 b = cal(root << 1 | 1, left, right);68 return a + b;69 }70 71 int main() {72 int t;73 int n, m;74 int a, b;75 scanf("%d",&t);76 while(t--) {77 scanf("%d %d",&n, &m);78 creat(1, 1, n);79 for(int i = 1; i <= m; i++) {80 scanf("%d %d",&a, &b);81 printf("%d\n", cal(1, a, b) );82 update(1, a, b);83 }84 }85 return 0;86 }
0 0
- hlgChocolate Auction【并查集】
- Auction
- Auction
- HDU3938 并查集 并查集
- 并查集(集并查)
- HDU1232 并查集<并>
- 并查集
- 数据结构-并查集
- 并查集
- 并查集!
- 并查集
- 并查集
- 并查集
- 并查集
- 并查集总结
- 并查集学习
- 并查集
- 并查集
- poj2155Matrix【二位树状数组】
- poj1840Eqs【散列表】
- HDU1496Equations【hash】
- 内存认识
- POJ2309BST【树状数组的理解】
- hlgChocolate Auction【并查集】
- hlg1287数字去重和排序II【hash】
- 转型之路
- android icon 大小
- JSLint使用教程
- poj1007【求逆序数】
- 0926
- hdu5045||2014 ACM/ICPC Asia Regional Shanghai Online【数位dp】
- 2014 ACM/ICPC Asia Regional Shanghai Online【未完成】