2017 Multi-University Training Contest - Team 9 1001&&HDU 6161 Big binary tree【树形dp+hash】
Big binary tree
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 597 Accepted Submission(s): 207
You are given a complete binary tree with n nodes. The root node is numbered 1, and node x's father node is ⌊x/2⌋. At the beginning, node x has a value of exactly x. We define the value of a path as the sum of all nodes it passes(including two ends, or one if the path only has one node). Now there are two kinds of operations:
1. change u x Set node u's value as x(1≤u≤n;1≤x≤10^10)
2. query u Query the max value of all paths which passes node u.
For each case:
The first line contains two integers n,m(1≤n≤10^8,1≤m≤10^5), which represent the size of the tree and the number of operations, respectively.
Then m lines follows. Each line is an operation with syntax described above.
6 13 query 1 query 2 query 3 query 4 query 5 query 6 change 6 1 query 1 query 2 query 3 query 4 query 5 query 6
17 17 17 16 17 17 12 12 12 11 12 12
考虑快速算 f(x) 对于子树内没有被修改过的点的 f(x) 可以快速分类讨论算出,而不满足本条件的点只有 O(mlogm) 个,在hash上dp即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb push_back 4 #define mkp make_pair 5 #define fi first 6 #define se second 7 #define ll long long 8 #define M 1000000007 9 #define all(a) a.begin(), a.end() 10 11 int n, m; 12 char s[20]; 13 map<int, ll> mp; 14 map<int, int> amp; 15 16 inline ll askmax(int u){ 17 if(u > n) return 0; 18 if(mp.count(u)) return mp[u]; 19 else{ 20 int l = u, r = u; 21 while(l * 2 <= n){ 22 l <<= 1; 23 r = (r << 1) | 1; 24 } 25 r = min(r, n); 26 ll res = 0; 27 while(r >= u) res += r, r >>= 1; 28 return res; 29 } 30 } 31 32 inline int ask(int x){ 33 return amp.count(x) ? amp[x] : x; 34 } 35 36 int main(){ 37 while(~scanf("%d%d", &n, &m)){ 38 mp.clear(); 39 amp.clear(); 40 while(m--){ 41 int x, v; 42 scanf("%s", s); 43 if(s[0] == 'c'){ 44 scanf("%d%d", &x, &v); 45 amp[x] = v; 46 for(; x; x >>= 1) 47 mp[x] = max(askmax(x << 1), askmax((x << 1) | 1)) + ask(x); 48 }else{ 49 scanf("%d", &x); 50 int px = x; 51 ll res = 0, now = 0; 52 for(; x >> 1;){ 53 bool k = ~x & 1; x >>= 1; 54 now += ask(x); 55 ll tmp = askmax(x << 1 | k); 56 if(now + tmp > res) res = now + tmp; 57 } 58 res += askmax(px); 59 res = max(res, askmax(px << 1) + askmax(px << 1 | 1) + ask(px)); 60 printf("%lld\n", res); 61 } 62 } 63 } 64 65 #ifndef ONLINE_JUDGE 66 system("pause"); 67 #endif 68 return 0; 69 }
作 者:Angel_Kitty
出 处:https://www.cnblogs.com/ECJTUACM-873284962/
关于作者:阿里云ACE,目前主要研究方向是Web安全漏洞以及反序列化。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!
欢迎大家关注我的微信公众号IT老实人(IThonest),如果您觉得文章对您有很大的帮助,您可以考虑赏博主一杯咖啡以资鼓励,您的肯定将是我最大的动力。thx.
我的公众号是IT老实人(IThonest),一个有故事的公众号,欢迎大家来这里讨论,共同进步,不断学习才能不断进步。扫下面的二维码或者收藏下面的二维码关注吧(长按下面的二维码图片、并选择识别图中的二维码),个人QQ和微信的二维码也已给出,扫描下面👇的二维码一起来讨论吧!!!
欢迎大家关注我的Github,一些文章的备份和平常做的一些项目会存放在这里。