hdu 5186 zhx's submissions 5187 zhx's contest快速幂小优化

来源:互联网 发布:蓝桥杯c语言试题 编辑:程序博客网 时间:2024/05/17 04:24

5186:求各个数位上的和并%k,k为k进制。要交c++

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 100005;typedef long long LL;int n , Q;int res[205];char str[205];void work() {    int mx = 0;    memset(res , 0 , sizeof(res));    for (int i = 0 ; i < n ; ++ i) {        scanf("%s" , str);        int len = strlen(str);        reverse(str , str + len);        for (int j = 0 ; j < len ; ++ j)            if (isdigit(str[j]))                res[j] += str[j] - '0';            else                res[j] += str[j] - 'a' + 10;        mx = max(len , mx);    }    for (int i = 0 ; i < mx ; ++ i)        res[i] %= Q;            while (mx > 1 && res[mx - 1] == 0)        -- mx;    for (int i = mx - 1 ; i >= 0 ; -- i) {        if (res[i] < 10)            printf("%d" , res[i]);        else            printf("%c" , res[i] - 10 + 'a');    }    puts("");}int main() {    while (~scanf("%d%d",&n,&Q))        work();    return 0;}

5187:n个从1到n的数重新排成一个序列,允许序列出现一个峰(最高峰或最低峰)

可知,整个序列中只有最两边的位置一定是存在一个n或者是1的,否则若1和n这两个数都在序列中间的话,整个序列势必会出现两个峰而不满足条件。那么接下来我们开始讨论:1:1放在最左,然后考虑n所在的位置(假设都是从左往右),在第二位时所有可能是C( 0,n-2),第三位为C(1,n-2)...一直到最有,共有X = c(0,n-2)+c(1,n-2).....c(n-2,n-2) = 2^(n-1)-1种可能,然后把1放在最右同理,再将1换成n,再算一次,所以一共是有X × 2 × 2 = 2 ^ n - 4,但是中间算的过程中多减去两次(1...n) (n...1)的情况,所以加回来,那么最终答案是ans = 2 ^ n - 2,。很明显用快速幂,但是n高达10^18,在裸快速幂计算过程中肯定会爆LL,因此将中间再次二进制拆分下,时间变成lgn*lgn,就能接受了

#include <map>#include <set>#include <queue>#include <stack>#include <vector>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1#define pi acos(-1.0)#define eps 1e-8typedef long long ll;const int inf = 0x3f3f3f3f;ll n, x;ll multi( ll a, ll b ){ll res = 0;while( b ){if( b & 1 ){res += a;res %= x;}a += a, a %= x, b >>= 1;}return res;}ll power( ll a, ll b ){ll res = 1;while( b ){if( b & 1 ){res = multi( res, a );}a = multi( a, a ), b >>= 1;}return res;}int main(){while( cin >> n >> x ){if( n == 1 ){cout << 1 % x << endl;continue;}else{ll ans = power( 2, n ) - 2;while( ans < 0 )ans += x;cout << ans << endl;}}return 0;}


0 0