HDU 6161 (2017多校9 - STL模拟 + dp)
2017-08-25 08:06
253 查看
题意:
给你一个n (n <= 1e8)个节点的完全二叉树, 开始时,每个节点的权值 为他本身, 两种操作:
1. 查询经过节点x 的最大权值链。
2. 改变x 的权值为v
思路:
n是1e8,没法建树。
但他是一个完全二叉树,一条链就log n 个点。
那么我们每次修改权值时 , 维护一下这条链的信息。 那么我们只需要n log n 的空间就足够了。
所有 我们令dp[x]表示 从x 往下走 最大权值是多少。
val[x]表示 x 这个点权值是多少,如果没有, 表示为本身(初始状态)
然后就是模拟就行了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
map<int, long long >dp, val;
char s[10];
int n, q;
long long calc(int x){
if (x > n) return 0;
if (dp.count(x)) return dp[x];
int d1 = 0;
int d2 = 0;
int x2 = x;
while(x2 <= n){
++d1;
x2 = x2 * 2 + 1;
}
int x3 = x;
while(x3 <= n){
++d2;
x3 = x3 * 2;
}
long long sum = 0;
if (x2 > n){
x2 >>= 1;
}
while(x2 != x){
sum += x2;
x2 /= 2;
}
sum += x2;
long long ans = sum;
sum = 0;
if (d1 != d2){
x2 = n;
while(x2 != x){
sum += x2;
x2 /= 2;
}
sum += x2;
ans = max(ans, sum);
}
return ans;
}
void change(int x,long long v){
val[x] = v;
dp[x] = max(calc(x<<1), calc(x << 1 | 1)) + v;
int md = x % 2;
long long ans = max(calc(x<<1) , calc(x << 1 | 1)) + v;
x/= 2;
while(x > 1){
long long t;
if (val.count(x)) t = val[x];
else t = x;
// ans += t;
if (md){
dp[x] = max(calc(x << 1), ans) + t;
}
else {
dp[x] = max(ans, calc(x<<1|1) ) + t;
}
ans = dp[x];
md = x % 2;
x /= 2;
}
}
long long query(int x){
long long t;
if (val.count(x)) t = val[x];
else t = x;
long long ans = calc(x << 1) + calc(x << 1 | 1) + t;
long long tmp = calc(x);
int md = x % 2;
x >>= 1;
while(x >= 1){
if (val.count(x))t = val[x];
else t = x;
tmp += t;
if (md){
ans = max(ans, calc(x << 1) + tmp);
}
else {
ans = max(ans, calc(x<<1|1) + tmp);
}
md = x % 2;
x /= 2;
}
return ans;
}
int main(){
while(~scanf("%d %d",&n, &q)){
val.clear();
dp.clear();
for (int i = 0; i < q; ++i){
scanf("%s", s);
if (s[0] == 'q'){
int x;
scanf("%d",&x);
long long ans = query(x);
printf("%I64d\n", ans);
}
else {
int x;
long long v;
scanf("%d%I64d", &x, &v);
change(x, v);
}
}
}
return 0;
}
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 492 Accepted Submission(s): 168
Problem Description
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.
Input
There are multiple cases.
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.
Output
For each query operation, output an integer in one line, indicating the max value of all paths which passes the specific node.
Sample Input
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
Sample Output
17
17
17
16
17
17
12
12
12
11
12
12
Source
2017 Multi-University Training Contest - Team 9
Recommend
liuyiding | We have carefully selected several similar problems for you: 6181 6180 6179 6178 6177
Statistic | Submit | Discuss | Note
给你一个n (n <= 1e8)个节点的完全二叉树, 开始时,每个节点的权值 为他本身, 两种操作:
1. 查询经过节点x 的最大权值链。
2. 改变x 的权值为v
思路:
n是1e8,没法建树。
但他是一个完全二叉树,一条链就log n 个点。
那么我们每次修改权值时 , 维护一下这条链的信息。 那么我们只需要n log n 的空间就足够了。
所有 我们令dp[x]表示 从x 往下走 最大权值是多少。
val[x]表示 x 这个点权值是多少,如果没有, 表示为本身(初始状态)
然后就是模拟就行了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
map<int, long long >dp, val;
char s[10];
int n, q;
long long calc(int x){
if (x > n) return 0;
if (dp.count(x)) return dp[x];
int d1 = 0;
int d2 = 0;
int x2 = x;
while(x2 <= n){
++d1;
x2 = x2 * 2 + 1;
}
int x3 = x;
while(x3 <= n){
++d2;
x3 = x3 * 2;
}
long long sum = 0;
if (x2 > n){
x2 >>= 1;
}
while(x2 != x){
sum += x2;
x2 /= 2;
}
sum += x2;
long long ans = sum;
sum = 0;
if (d1 != d2){
x2 = n;
while(x2 != x){
sum += x2;
x2 /= 2;
}
sum += x2;
ans = max(ans, sum);
}
return ans;
}
void change(int x,long long v){
val[x] = v;
dp[x] = max(calc(x<<1), calc(x << 1 | 1)) + v;
int md = x % 2;
long long ans = max(calc(x<<1) , calc(x << 1 | 1)) + v;
x/= 2;
while(x > 1){
long long t;
if (val.count(x)) t = val[x];
else t = x;
// ans += t;
if (md){
dp[x] = max(calc(x << 1), ans) + t;
}
else {
dp[x] = max(ans, calc(x<<1|1) ) + t;
}
ans = dp[x];
md = x % 2;
x /= 2;
}
}
long long query(int x){
long long t;
if (val.count(x)) t = val[x];
else t = x;
long long ans = calc(x << 1) + calc(x << 1 | 1) + t;
long long tmp = calc(x);
int md = x % 2;
x >>= 1;
while(x >= 1){
if (val.count(x))t = val[x];
else t = x;
tmp += t;
if (md){
ans = max(ans, calc(x << 1) + tmp);
}
else {
ans = max(ans, calc(x<<1|1) + tmp);
}
md = x % 2;
x /= 2;
}
return ans;
}
int main(){
while(~scanf("%d %d",&n, &q)){
val.clear();
dp.clear();
for (int i = 0; i < q; ++i){
scanf("%s", s);
if (s[0] == 'q'){
int x;
scanf("%d",&x);
long long ans = query(x);
printf("%I64d\n", ans);
}
else {
int x;
long long v;
scanf("%d%I64d", &x, &v);
change(x, v);
}
}
}
return 0;
}
Big binary tree
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 492 Accepted Submission(s): 168
Problem Description
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.
Input
There are multiple cases.
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.
Output
For each query operation, output an integer in one line, indicating the max value of all paths which passes the specific node.
Sample Input
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
Sample Output
17
17
17
16
17
17
12
12
12
11
12
12
Source
2017 Multi-University Training Contest - Team 9
Recommend
liuyiding | We have carefully selected several similar problems for you: 6181 6180 6179 6178 6177
Statistic | Submit | Discuss | Note
相关文章推荐
- HDU-2017 多校训练赛9-1006-Senior Pan
- HDU-2017 多校训练赛10-1010-Schedule
- HDU-2017 多校训练赛10-补题
- HDU 6043 (2017 多校训练赛1 1002) Balala Power!
- HDU 6038 (2017 多校训练赛1 1006) Function(图论)
- 2017 HDU 多校联合赛 Balala Power!
- HDU-2017 多校训练赛1-1008-Hints of sd0061
- HDU-2017 多校训练赛6-1011-Classes
- hdu 6053: TrickGCD (2017 多校第二场 1009) 【莫比乌斯 容斥原理】
- 2017多校联合第二场 1001题 hdu 6045 Is Derek lying?
- HDU 2017 多校联合训练赛6 1010 6105 Gameia
- HDU-2017 多校训练赛9-1008-Numbers
- 2017 第十场多校训练 HDU 6181 Two Paths 次短路+Dijkstra
- 2017 多校3 hdu 6061 RXD and functions
- HDU 6127 Hard challenge+HDU 6129 Just do it【2017多校联赛】
- HDU-2017 多校训练赛8-补题
- HDU-2017 多校训练赛4-1007-Matching In Multiplication
- HDU-2017 多校训练赛1-补题
- HDU 2017多校联赛-1011 KazaQ's Socks
- HDU 6092 Rikka with Subset (2017多校5-背包)