• 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(济南)-L Bit Sequence


    题意

    给你两个数l,m,大小为m的数组a,求[0,l]之间满足以下条件的数x的个数:
    对于任何i输入[0,m-1],f(x+i)%2=a[i];f(k):代表k在二进制下1的个数
    m的范围<=100,l<=1e18,a[i] = 0/1

    思路

    显然l的范围1e18,大概率就是数位DP了

    1. 观察到m是<=100的,因此x+m只会改变后7位置,对于前面的位数,则只会进1,使得前面连续的0变成1;
    2. 那么只要对前半部分进行数位DP,dp[pos][lim][cnt][d]代表位置在pos处,lim代表有无达到上限,cnt为1代表前面有奇数个1为0代表偶数个1,d代表从pos起向前有偶数还是奇数个1;
    3. 对于第七位以后的部分,直接暴力计算就好了,统计一下是否进位;

    代码

    #include
    
    using namespace std;
    #define  int long long
    int a[105];
    vector<int> b;
    int mp[80][2][2][2];
    int mx;
    int m, l;
    
    int clc(int lim, int cnt, int h) {
       int up = (1 << 7) - 1;
       if (lim) up = mx;
       int all = 0;
       int cc = cnt;
       for (int i = 0; i <= up; i++) {
           bool flag = 1;
           for (int j = 0; j < m; j++) {
               cnt = cc;
               int res = i + j;
               int sum = __builtin_popcount(res);
               cnt += sum;
               cnt &= 1;
               if (res > ((1 << 7) - 1))cnt = (cnt + h) & 1;
               if (cnt != a[j])flag = 0;
           }
    //        if (flag)cout << i << '\n';
           all += flag;
       }
       return all;
    }
    
    long long DFS(int pos, int lim, int cnt, int h) {
       if (mp[pos][lim][cnt][h] != -1)return mp[pos][lim][cnt][h];
       long long ans = 0;
       if (pos <= 6)return clc(lim, cnt, h);
       if (lim) {
           for (int i = 0; i <= b[pos]; i++) {
               bool ok = (i == b[pos]);
               int hh = 0;
               if (i == 0)hh = 0;
               else
                   hh = (h + 1) & 1;
               ans += DFS(pos - 1, ok, (cnt + (i == 1)) & 1, hh);
           }
       } else {
           for (int i = 0; i <= 1; i++) {
    //            bool ok = (i == b[pos]);
               int hh = 0;
               if (i == 0)hh = 0;
               else
                   hh = (h + 1) & 1;
               ans += DFS(pos - 1, 0, (cnt + (i == 1)) & 1, hh);
           }
       }
       return mp[pos][lim][cnt][h] = ans;
    }
    
    void run() {
    
       cin >> m >> l;
       for (int i = 0; i < m; i++) {
           cin >> a[i];
       }
       b.clear();
       memset(mp, -1, sizeof mp);
       for (int i = l; i; i >>= 1) {
           b.emplace_back(i & 1);
       }
       mx = l & ((1 << 7) - 1);
       cout << DFS(b.size() - 1, 1, 0, 0) << '\n';
    
    
    }
    
    signed main() {
    
       int t;
       cin >> t;
       while (t--)
           run();
       return 0;
    }
    
    
  • 相关阅读:
    Python二级 每周练习题21
    前端周刊第三十四期
    游戏开发玩法设计的重要性
    Java EE——JVM基础知识
    让资产权利归于建设者:Kiosk使过程变得更简单
    【附源码】计算机毕业设计JAVA疫情期间物资分派管理系统
    基础模型量化学习扩展仓库
    Huffman哈夫曼树思想即代码
    Kubernetes部署
    squid代理服务器
  • 原文地址:https://www.cnblogs.com/4VDP/p/16855983.html