博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
可并堆/左偏树 题目泛做
阅读量:6673 次
发布时间:2019-06-25

本文共 6639 字,大约阅读时间需要 22 分钟。

题目1 BZOJ1455 罗马游戏

可并堆 + 并查集维护,是个可并堆的裸题。

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 8 using namespace std; 9 10 const int N = 1000000 + 5;11 typedef long long ll;12 13 char ss[5];14 int n, m, val[N], fa[N];15 bool sile[N];16 17 inline int read() {18 int x = 0;19 char c = getchar();20 21 while(!isdigit(c)) c = getchar();22 while(isdigit(c)) {23 x = x * 10 + c - '0';24 c = getchar();25 }26 return x;27 }28 29 struct Node {30 int v, dis, l, r;31 32 bool operator < (const Node &a) const {33 return v < a.v;34 }35 }t[N];36 37 int merge(int A, int B) {38 if(A == 0 || B == 0) return A + B;39 if(t[A].v > t[B].v) swap(A, B);40 t[A].r = merge(t[A].r, B);41 if(t[A].r) {42 if(t[t[A].r].dis > t[t[A].l].dis) {43 swap(t[A].r, t[A].l);44 }45 }46 t[A].dis = t[A].r ? t[t[A].r].dis + 1 : 0;47 return A;48 }49 50 int find(int x) {51 return fa[x] == x ? x : (fa[x] = find(fa[x]));52 }53 54 int main() {55 int x, y, fx, fy, p;56 57 n = read();58 for(int i = 1; i <= n; ++ i) t[i].v = read();59 for(int i = 1; i <= n; ++ i) fa[i] = i;60 m = read();61 for(int i = 1; i <= m; ++ i) {62 scanf("%s", ss);63 if(ss[0] == 'M') {64 scanf("%d%d", &x, &y);65 if(sile[x] || sile[y]) continue;66 fx = find(x); fy = find(y);67 if(fx != fy) {68 p = merge(fx, fy);69 fa[fx] = fa[fy] = p;70 }71 }72 else if(ss[0] == 'K') {73 scanf("%d", &x);74 if(sile[x]) {75 puts("0"); continue;76 }77 p = find(x); sile[p] = true;78 printf("%d\n", t[p].v);79 fa[p] = merge(t[p].l, t[p].r);80 fa[fa[p]] = fa[p];81 }82 }83 return 0;84 }
BZOJ

 

题目2 BZOJ 4003 [JLOI2015]攻占城池

带标记的可并堆,注意的一个问题就是在KILL完根结点之后,把没有KILL掉的点再PUSHDOWN一下。否则你会WA死的。

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 8 using namespace std; 9 10 const int N = 300000 + 5; 11 typedef long long ll; 12 13 int n, m, cnt; 14 int fa[N], a[N], root[N], head[N]; 15 int tmp[N], city[N], c[N]; 16 int lz[N], gz[N], ans[N]; 17 ll h[N], vv[N], s[N]; 18 19 struct Edge { 20 int from, to, next; 21 }edges[N << 1]; 22 23 struct Node { 24 ll v, mu, ad; 25 int dis, l, r, id; 26 Node() { mu = 1;} 27 bool operator < (const Node &k) const { 28 return v < k.v; 29 } 30 }t[N]; 31 32 void pushdown(int x) { 33 if(!x) return; 34 35 int l = t[x].l, r = t[x].r; 36 37 if(t[x].mu != 1) { 38 if(l) { t[l].v *= t[x].mu; t[l].mu *= t[x].mu; t[l].ad *= t[x].mu;} 39 if(r) { t[r].v *= t[x].mu; t[r].mu *= t[x].mu; t[r].ad *= t[x].mu;} 40 t[x].mu = 1; 41 } 42 if(t[x].ad) { 43 if(l) { t[l].v += t[x].ad; t[l].ad += t[x].ad;} 44 if(r) { t[r].v += t[x].ad; t[r].ad += t[x].ad;} 45 t[x].ad = 0; 46 } 47 if(lz[x]) { 48 if(l) { lz[l] += lz[x]; gz[l] += lz[x];} 49 if(r) { lz[r] += lz[x]; gz[r] += lz[x];} 50 lz[x] = 0; 51 } 52 } 53 54 int merge(int s1, int s2) { 55 if(!s1 || !s2) return s1 + s2; 56 pushdown(s1); pushdown(s2); 57 if(t[s1].v > t[s2].v) swap(s1, s2); 58 t[s1].r = merge(t[s1].r, s2); 59 if(t[s1].r) 60 if(t[t[s1].r].dis > t[t[s1].l].dis) 61 swap(t[s1].r, t[s1].l); 62 t[s1].dis = t[s1].r ? t[t[s1].r].dis + 1 : 0; 63 return s1; 64 } 65 66 void insert(int from, int to) { 67 ++ cnt; 68 edges[cnt].from = from; 69 edges[cnt].to = to; 70 edges[cnt].next = head[from]; 71 head[from] = cnt; 72 } 73 74 void dfs(int x) { 75 for(int i = head[x]; i; i = edges[i].next) { 76 int v = edges[i].to; 77 78 if(v != fa[x]) dfs(v); 79 } 80 while(root[x] && t[root[x]].v < h[x]) { 81 city[x] ++; 82 pushdown(root[x]); 83 ans[t[root[x]].id] = gz[root[x]]; 84 root[x] = merge(t[root[x]].l, t[root[x]].r); 85 } 86 if(root[x]) { 87 if(a[x] == 0) { t[root[x]].v += vv[x]; t[root[x]].ad += vv[x];} 88 else if(a[x] == 1) { t[root[x]].v *= vv[x]; t[root[x]].mu *= vv[x]; t[root[x]].ad *= vv[x];} 89 lz[root[x]] ++; gz[root[x]] ++; 90 root[fa[x]] = merge(root[fa[x]], root[x]); 91 } 92 } 93 94 int main() { 95 scanf("%d%d", &n, &m); 96 for(int i = 1; i <= n; ++ i) scanf("%lld", &h[i]); 97 a[1] = -1; 98 for(int i = 1; i < n; ++ i) { 99 scanf("%d%d%lld", &fa[i + 1], &a[i + 1], &vv[i + 1]);100 insert(i + 1, fa[i + 1]); insert(fa[i + 1], i + 1);101 }102 for(int i = 1; i <= m; ++ i) {103 scanf("%lld%d", &s[i], &c[i]);104 t[i].v = s[i]; t[i].id = i;105 root[c[i]] = merge(root[c[i]], i);106 }107 dfs(1);108 while(root[1]) {109 pushdown(root[1]);110 ans[t[root[1]].id] = gz[root[1]];111 root[1] = merge(t[root[1]].l, t[root[1]].r);112 }113 for(int i = 1; i <= n; ++ i) printf("%d\n", city[i]);114 for(int i = 1; i <= m; ++ i) printf("%d\n", ans[i]);115 return 0;116 }
BZOJ 4003

 

题目3 BZOJ 2809 APIO dispatching

要注意的一个地方就是在合并堆的时候,由于我们要维护的是一个大根,所以关键字的比较要以两个节点的cost值,而我用的是v值,

所以导致WA了许多遍。题目的思路就是DFS过程中每次把当前点与儿子们合并,然后如果sum值大于lim值就把最大的去掉。一直搞到

最后就可以了。

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 8 using namespace std; 9 10 typedef long long ll;11 const int N = 100000 + 5;12 13 inline int read() {14 int x = 0;15 char c = getchar();16 17 while(!isdigit(c)) c = getchar();18 while(isdigit(c)) {19 x = x * 10 + c - '0';20 c = getchar();21 }22 return x;23 }24 25 int n, fa[N], head[N], master, cnt, root[N];26 ll cost[N], ship[N], lim, ans;27 28 struct Edge {29 int from, to, next;30 }edges[N << 1];31 32 struct Node {33 ll v; int l, r, sz, dis;34 }t[N];35 36 void insert(int u, int v) {37 ++ cnt;38 edges[cnt].from = u; edges[cnt].to = v;39 edges[cnt].next = head[u]; head[u] = cnt;40 }41 42 int merge(int a, int b) {43 if(!a || !b) return a + b;44 if(cost[a] < cost[b]) swap(a, b);45 t[a].r = merge(t[a].r, b);46 if(t[a].r)47 if(t[t[a].l].dis < t[t[a].r].dis)48 swap(t[a].r, t[a].l);49 t[a].dis = t[a].r ? t[t[a].r].dis + 1 : 0;50 return a;51 }52 53 void dfs(int u) {54 t[u].v = cost[u]; t[u].sz = 1; root[u] = u;55 for(int i = head[u]; i; i = edges[i].next) {56 int v = edges[i].to;57 if(v != fa[u]) {58 dfs(v);59 t[u].v += t[v].v;60 t[u].sz += t[v].sz;61 root[u] = merge(root[u], root[v]);62 }63 }64 while(t[u].v > lim) {65 t[u].v -= cost[root[u]];66 t[u].sz --;67 root[u] = merge(t[root[u]].l, t[root[u]].r);68 }69 ans = max(ans, 1LL * t[u].sz * ship[u]);70 }71 72 int main() {73 n = read(); lim = read();74 for(int i = 1; i <= n; ++ i) {75 fa[i] = read(); cost[i] = read(); ship[i] = read();76 insert(fa[i], i); insert(i, fa[i]);77 if(!fa[i]) master = i;78 }79 dfs(master);80 printf("%lld\n", ans);81 return 0;82 }
BZOJ 2809

 

转载于:https://www.cnblogs.com/sxprovence/p/5274648.html

你可能感兴趣的文章
Libevent学习-02:搭建CentOS下的开发环境
查看>>
java操作Excel、word和pdf
查看>>
阿里巴巴常考面试题及汇总答案
查看>>
yum install 与 yum groupinstall 的区别
查看>>
Docker Swarm 编排及部署 PostGIS,并操作 GIS 数据
查看>>
当区块链遇上人工智能,这次变革的意义到底有多重大?
查看>>
Linux下安装python
查看>>
Go基础系列:读取标准输入(一)
查看>>
CAD打印文字不显示怎么办
查看>>
js正则表达式全文关键字搜索并高亮
查看>>
Java代理模式
查看>>
PHP协程入门详解
查看>>
Java_Reflect_1
查看>>
HTML中的<table>标签及其子元素标签,JS中DOM对<table>的操作
查看>>
在linux中执行wget命令提示 -bash: wget: command not found 解决方法
查看>>
MobPush推送证书制作
查看>>
springmvc源码解析之配置加载ContextLoadListener
查看>>
SVN就是这么简单
查看>>
网站安全防护工作
查看>>
Java gc中能聊的那些事
查看>>