zoukankan      html  css  js  c++  java
  • Codeforces Round #362 (Div. 2) C. Lorenzo Von Matterhorn (类似LCA)

    题目链接:http://codeforces.com/problemset/problem/697/D

    给你一个有规则的二叉树,大概有1e18个点。

    有两种操作:1操作是将u到v上的路径加上w,2操作是求u到v上的路径和。

    我们可以看出任意一个点到1节点的边个数不会超过64(差不多就是log2(1e18)),所以可以找最近相同祖节点的方式写。

    用一条边的一个唯一的端点作为边的编号(比如1到2,那2就为这条边的编号),由于数很大,所以用map来存。

    进行1操作的时候就是暴力加w至u到LCA(u,v)上的各个边,同样加w至v到LCA(u , v)上的各个边。同理,进行2操作的时候也是暴力求和。

    下面这是简单的写法

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef __int64 LL;
     4 map <LL , LL> cnt;
     5 
     6 int main()
     7 {
     8     int n;
     9     LL choose , u , v , val;
    10     scanf("%d" , &n);
    11     while(n--) {
    12         scanf("%lld" , &choose);
    13         if(choose == 1) {
    14             scanf("%lld %lld %lld" , &u , &v , &val);
    15             while(u != v) {
    16                 if(u > v) {
    17                     cnt[u] += val;
    18                     u /= 2;
    19                 }
    20                 else {
    21                     cnt[v] += val;
    22                     v /= 2;
    23                 }
    24             }
    25         }
    26         else {
    27             scanf("%lld %lld" , &u , &v);
    28             LL res = 0;
    29             while(u != v) {
    30                 if(u > v) {
    31                     res += cnt[u];
    32                     u /= 2;
    33                 }
    34                 else {
    35                     res += cnt[v];
    36                     v /= 2;
    37                 }
    38             }
    39             printf("%lld
    " , res);
    40         }
    41     }
    42     return 0;
    43 }

    下面是我一开始的写法,也A了,不过有点麻烦,可以不看。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef __int64 LL;
     4 const int N = 1e3 + 5;
     5 vector <int> vc;
     6 vector <LL> q1[N] , q2[N] , ans1 , ans2;
     7 LL x[N] , y[N] , val[N];
     8 int main()
     9 {
    10     int n;
    11     LL choose , u , v;
    12     scanf("%d" , &n);
    13     for(int i = 1 ; i <= n ; ++i) {
    14         scanf("%lld" , &choose);
    15         if(choose == 1) {
    16             scanf("%lld %lld %lld" , x + i , y + i , val + i);
    17             vc.push_back(i);
    18             LL num1 = x[i] , num2 = y[i];
    19             q1[i].push_back(num1) , q2[i].push_back(num2);
    20             while(num1 != num2) {
    21                 if(num1 > num2) {
    22                     num1 /= 2;
    23                     q1[i].push_back(num1);
    24                 }
    25                 else {
    26                     num2 /= 2;
    27                     q2[i].push_back(num2);
    28                 }
    29             }
    30         }
    31         else {
    32             scanf("%lld %lld" , &u , &v);
    33             LL temp1 = u , temp2 = v , res = 0;
    34             ans1.clear() , ans2.clear();
    35             ans1.push_back(temp1) , ans2.push_back(temp2);
    36             while(temp1 != temp2) {
    37                 if(temp1 > temp2) {
    38                     temp1 /= 2;
    39                     ans1.push_back(temp1);
    40                 }
    41                 else {
    42                     temp2 /= 2;
    43                     ans2.push_back(temp2);
    44                 }
    45             }
    46             for(int j = 0 ; j < vc.size() ; ++j) {
    47                 int l = 0 , r = ans1.size() - 1 , k = 0;
    48                 while(l + 1 <= r) {
    49                     for( ; k + 1 < q1[vc[j]].size() ; ++k) {
    50                         if(ans1[l] > q1[vc[j]][k])
    51                             break;
    52                         if(ans1[l + 1] == q1[vc[j]][k + 1] && ans1[l] == q1[vc[j]][k]) {
    53                             res += val[vc[j]];
    54                         }
    55                     }
    56                     l++;
    57                 }
    58                 k = 0 , l = 0 , r = ans1.size() - 1;
    59                 while(l + 1 <= r) {
    60                     for( ; k + 1 < q2[vc[j]].size() ; ++k) {
    61                         if(ans1[l] > q2[vc[j]][k])
    62                             break;
    63                         if(ans1[l + 1] == q2[vc[j]][k + 1] && ans1[l] == q2[vc[j]][k]) {
    64                             res += val[vc[j]];
    65                         }
    66                     }
    67                     l++;
    68                 }
    69                 
    70                 l = 0 , r = ans2.size() - 1 , k = 0;
    71                 while(l + 1 <= r) {
    72                     for( ; k + 1 < q1[vc[j]].size() ; ++k) {
    73                         if(ans2[l] > q1[vc[j]][k])
    74                             break;
    75                         if(ans2[l + 1] == q1[vc[j]][k + 1] && ans2[l] == q1[vc[j]][k]) {
    76                             res += val[vc[j]];
    77                         }
    78                     }
    79                     l++;
    80                 }
    81                 k = 0 , l = 0 , r = ans2.size() - 1;
    82                 while(l + 1 <= r) {
    83                     for( ; k + 1 < q2[vc[j]].size() ; ++k) {
    84                         if(ans2[l] > q2[vc[j]][k])
    85                             break;
    86                         if(ans2[l + 1] == q2[vc[j]][k + 1] && ans2[l] == q2[vc[j]][k]) {
    87                             res += val[vc[j]];
    88                         }
    89                     }
    90                     l++;
    91                 }
    92             }            
    93             printf("%lld
    " , res);
    94         }
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    Microsoft Internet Explorer 多个不明细节远程代码执行漏洞
    给妈妈写程序
    平安夜,100篇
    我的DV,Sony HC90E
    听相声
    嘉陵江的石头,也许吧
    一步一个脚印-产品升级随笔(3)-学会拍板
    一步一个脚印-产品升级随笔(1)-vision
    《网站重构》网络资源总结
    一步一个脚印-产品升级随笔(2)-为什么需要BS架构的产品
  • 原文地址:https://www.cnblogs.com/Recoder/p/5674195.html
Copyright © 2011-2022 走看看