Codeforces Round #362 (Div. 2) C.Lorenzo Von Matterhorn
2016-07-16 20:25
344 查看
题目链接:http://codeforces.com/contest/697/problem/C
题意:有1~n的n个点,对于第i个点它的2*i与2*i+1有一条无向的边。现在有两种操最,第一种是将从u到v的最短路径上所有边的 权值加上w。第二种是询问u到v最短路劲上的花费是多少。
解法:我们可以将从1开始将所有的边画出来,不难发现这就是一棵二叉树。他们的最短路径即为他们到公共父亲的距离。然后我们可以不断的将u,v中最大的除以二。我们就可以求出u,v最短路径所经过的点。u==v时,这就是他们的公共父亲。对于询问也可以同样处理。由于u,v超int了,我们可以用到map来映射。map[]映射的初始化默认值为0.
AC:
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define ll __int64
map<pair<ll,ll> ,ll> m;
ll q,u,v,w,t;
pair<ll,ll>tt;
void print()
{
cout<<tt.first<<" "<<tt.second<<" "<<m[tt]<<endl;
}
int main()
{
//freopen("in.txt","r",stdin);
m.clear();
scanf("%I64d",&q);
while(q--)
{
scanf("%I64d",&t);
if(t==1)
{
scanf("%I64d%I64d%I64d",&u,&v,&w);
while(u!=v)
{
if(u>v)
{
tt=make_pair(u,u/2);
m[tt]+=w;
u=u/2;
}
else if(u<v)
{
tt=make_pair(v,v/2);
m[tt]+=w;
v=v/2;
}
// print();
}
}
else
{
scanf("%I64d%I64d",&u,&v);
ll ans=0;
while(u!=v)
{
if(u>v)
{
tt=make_pair(u,u/2);
ans+=m[tt];
u=u/2;
}
else if(u<v)
{
tt=make_pair(v,v/2);
ans+=m[tt];
v=v/2;
}
//print();
}
printf("%I64d\n",ans);
}
}
}
题意:有1~n的n个点,对于第i个点它的2*i与2*i+1有一条无向的边。现在有两种操最,第一种是将从u到v的最短路径上所有边的 权值加上w。第二种是询问u到v最短路劲上的花费是多少。
解法:我们可以将从1开始将所有的边画出来,不难发现这就是一棵二叉树。他们的最短路径即为他们到公共父亲的距离。然后我们可以不断的将u,v中最大的除以二。我们就可以求出u,v最短路径所经过的点。u==v时,这就是他们的公共父亲。对于询问也可以同样处理。由于u,v超int了,我们可以用到map来映射。map[]映射的初始化默认值为0.
AC:
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define ll __int64
map<pair<ll,ll> ,ll> m;
ll q,u,v,w,t;
pair<ll,ll>tt;
void print()
{
cout<<tt.first<<" "<<tt.second<<" "<<m[tt]<<endl;
}
int main()
{
//freopen("in.txt","r",stdin);
m.clear();
scanf("%I64d",&q);
while(q--)
{
scanf("%I64d",&t);
if(t==1)
{
scanf("%I64d%I64d%I64d",&u,&v,&w);
while(u!=v)
{
if(u>v)
{
tt=make_pair(u,u/2);
m[tt]+=w;
u=u/2;
}
else if(u<v)
{
tt=make_pair(v,v/2);
m[tt]+=w;
v=v/2;
}
// print();
}
}
else
{
scanf("%I64d%I64d",&u,&v);
ll ans=0;
while(u!=v)
{
if(u>v)
{
tt=make_pair(u,u/2);
ans+=m[tt];
u=u/2;
}
else if(u<v)
{
tt=make_pair(v,v/2);
ans+=m[tt];
v=v/2;
}
//print();
}
printf("%I64d\n",ans);
}
}
}
相关文章推荐
- define和defined区别
- swift-闭包产生的循环引用以及解决办法
- 设二叉树结点的先根序列、中根序列和后根序列中,所有叶子结点的先后顺序____。
- JavaWeb工程中web.xml基本配置
- Eclipse配置
- 华为OJ——超长正整数相加
- 给定一个整数sum,从有N个无序元素的数组中寻找元素a、b、c、d,使得 a+b+c+d =sum,最快的平均时间复杂度是____。
- php模块memcache和memcached区别分析
- 华为OJ——尼科彻斯定理
- 优化 Lightmap
- 华为OJ——公共字串计算
- CodeForces 686C-Robbers' watch
- 华为OJ——参数解析
- fileno
- ICML2016最佳论文《深度强化学习的竞争网络架构》
- BZOJ 3043
- stdarg.h
- 华为OJ——计算日期到天数转换
- Socket介绍
- Linux安装samba服务