您的位置:首页 > 其它

CodeForces Round #287 Div.2

2015-01-26 02:04 295 查看
A. Amr and Music (贪心)

水题,没能秒切,略尴尬。

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long LL;

LL h, n, sum[55], ans = 0;
vector<LL> anc1;

int main()
{
//freopen("in.txt", "r", stdin);

for(int i = 0; i <= 50; ++i) sum[i] = (1LL << (i+1)) - 1;
scanf("%I64d%I64d", &h, &n);
n += sum[h-1];  //转化成整个二叉树中的编号
LL x = n;
anc1.push_back(x);  //目标节点的所有祖先
while(x != 1)
{
x /= 2;
anc1.push_back(x);
}
//for(int i = 0; i < anc1.size(); ++i) printf("%I64d  ", anc1[i]);

LL node = 1;
bool choice = false;    //遍历防线(L or R)

while(node != n)
{
vector<LL> anc2;    //当前叶子节点X的祖先
for(int i = 0; i < h; ++i)
{
anc2.push_back(node);
if(!choice) node = node * 2; else node = node * 2 + 1;
choice = !choice;
}
if(n == node) { ans += h; break; }
anc2.push_back(node);
reverse(anc2.begin(), anc2.end());
//for(int i = 0; i < anc2.size(); ++i) printf("%I64d  ", anc2[i]);

for(int i = 1; i <= h; ++i) if(anc1[i] == anc2[i])
{//find LCA
ans += sum[i-1] + h - i + 1;
h = i - 1;      //更新树高
node = anc2[i-1];
if((anc2[i]<<1) == node)    //更新根节点的编号 及 遍历方向
{
node = anc2[i] * 2 + 1;
choice = false;
}
else
{
node = (anc2[i] << 1);
choice = true;
}
break;
}
}

printf("%I64d\n", ans);

return 0;
}


代码君
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: