您的位置:首页 > 其它

NOIP模拟 9.09

2017-09-09 14:07 239 查看
AK300分


果实计数

(count.pas/.c/.cpp)

时间限制:1s,空间限制32MB

题目描述:

淘淘家有棵奇怪的苹果树,这棵树共有n+1层,标号为0~n。这棵树第0层只有一个节点,为根节点。已知这棵树为b叉树,且保证是一颗满b叉树。如图为一颗满3叉树。

现在,该树第n层的每个节点上都结出了一个苹果,淘淘想知道共结了多少苹果。由于数量可能很大,答案要求输出mod k后的结果。

输入描述:

给出第1层的节点数b和层数n和k.

输出描述:

输出苹果数mod k后的结果。

样例输入:

2 10 9

样例输出:

7

数据范围:

30%的数据保证:b<=100,n<=10, k<=100.

100%的数据保证:b<2^31,n<2^31,k<=2^15.

【题解】

嗯?求n层完全b叉树的节点数?

嗯。。等比数列求和公式。。不对,模数是k,1-q不一定有逆元。。嗯。分治nlog^2n算法。。

嗯。。嗯?

求完全b叉树第n层节点数?

woccccccccc

这题太神辣!!

传说中的二进制拆分倍增算法啊!

(简称快速幂)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define min(a, b) ((a) < (b) ? (a) : (b))

inline void read(int &x)
{
x = 0;char ch = getchar(), c = ch;
while(ch < '0' || ch > '9')c = ch, ch = getchar();
while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
if(c == '-')x = -x;
}

int num[6],ans[14][14][14][14][14];

int main()
{
register int t;
read(t);
register int sum,a,b,c,d,e,ta,tb,tc,td,te;
for(a = 1;a <= 13;++ a)
for(b = 1;b <= 13;++ b)
for(c = 1;c <= 13;++ c)
for(d = 1;d <= 13;++ d)
for(e = 1;e <= 13;++ e)
{
if(a < 5 && b < 5 && c < 5 && d < 5 && e < 5 && a + b + c + d + e <= 10)
{
ans[a][b][c][d][e] = 60;
}
else if(a > 10 && b > 10 && c > 10 && d > 10 && e > 10)
{
ans[a][b][c][d][e] = 50;
}
else if((a == b&&b==c&&c==d) || (a==b&&b==c&&c==e) || (a==b&&b==d&&d==e) || (b==c&&c==d&&d==e) || (a==c&&c==d&&d==e))
{
ans[a][b][c][d][e] = 40;
}
else
{
ta = min(10, a), tb = min(10, b), tc = min(10, c), td = min(10, d), te = min(10, e);
if((ta + tb + tc)%10 == 0 || (ta + tb + td)%10 == 0 || (ta + tb + te)%10 == 0 || (tb + tc + td)%10 == 0 || (tb + tc + te)%10 == 0 || (ta + tc + td)%10 == 0 || (ta + tc + te)%10 == 0 || (ta + td + te)%10 == 0 || (tb + td + te)%10 == 0 || (tc + td + te)%10 == 0)
{
sum = ta + tb + tc + td + te;
if(sum%10 == 0) ans[a][b][c][d][e] = 30;
else if(sum%10 < 7)ans[a][b][c][d][e] = sum%10;
else ans[a][b][c][d][e] = (sum%10)*2;
}
else
{
ans[a][b][c][d][e] = 0;
}
}
}
for(;t;--t)
{
read(num[1]),read(num[2]),read(num[3]),read(num[4]);
sum = 0;
for(register int i = 1;i <= 13;++ i)
{
num[5] = i;
sum += ans[num[1]][num[2]][num[3]][num[4]][num[5]];
}
sum = (sum/13.0) + 0.5;
printf("%d\n", sum);
}
return 0;
}


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