zoukankan      html  css  js  c++  java
  • hihocoder Challenge 29 A.序列的值

    我现在就感觉我这人现在真的没有dp的意识
    其实真写起来也不难,但是把就是练的少思维跟不上,dp从根本上就是一种状态的提炼和聚集。

    按照题解的意思来,dp[i][j]表示二进制第i位的值为j(0,1)的组合有多少,然后滚动数组

    今天补完之后感觉,除了fft,我懒得抄板子就不补了,其他三题,代码难度都不大。爆零也就算买个教训,希望7.8codem好好打

    #include<cmath>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<set>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 1e5+5;
    const int INF = 0x3f3f3f3f;
    const int MOD = 998244353;
    #define MP(x, y) make_pair(x, y)
    
    int a[N];
    int dp[2][35][2];
    int two[N];
    void gadd(int &a, int b) {
        a += b;
        if(a >= MOD) a -= MOD;
    }
    int main() {
        int n;
        two[0] = 1;
        for(int i = 1; i < N; ++i) {
            two[i] = 1ll*two[i-1] *2 %MOD;
        }
     // printf("%d
    ", two[1]);
        while(~scanf("%d", &n)) {
            memset(dp, 0, sizeof(dp));
    
            for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
            int fl = 0;
            ll ans = 0;
    
            for(int i = 1; i <= n; ++i) {
                for(int j = 30; j >= 0; --j) {
                    int tt = a[i]>>j&1;
                    if(!tt) continue;
                    else {
                        ans = (ans + 1ll* two[n-i] * (1+dp[fl][j][0]) ) % MOD;
                        break;
                    }
                }   
            //  printf("%d
    ", ans);
                for(int j = 0; j <= 30; ++j) {
                    gadd(dp[fl^1][j][0], dp[fl][j][0]);
                    gadd(dp[fl^1][j][1], dp[fl][j][1]);
                }
                for(int j = 0; j <= 30; ++j) {
                    int tt = a[i]>>j & 1;
                    gadd(dp[fl ^ 1][j][tt], 1);
                    gadd(dp[fl ^ 1][j][tt^1], dp[fl][j][1]);
                    gadd(dp[fl ^ 1][j][tt^0], dp[fl][j][0]);
                }
                fl ^= 1;
                memset(dp[fl ^ 1], 0, sizeof(dp[fl ^ 1]));
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    [国家集训队]整数的lqp拆分
    来一波全套向量运算(C++)
    天哪又要搬家啦qvq
    利用输入输出流复制文件
    系统会随机给你两个日期(yyyy-MM-dd),求出两个日期的具体相差天数
    mysql中的连接操作
    java面试题集锦
    Java关于Math类的三个取整方法
    设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
    MySql5.5安装详细说明
  • 原文地址:https://www.cnblogs.com/Basasuya/p/8433694.html
Copyright © 2011-2022 走看看