zoukankan      html  css  js  c++  java
  • 4513: [Sdoi2016]储能表

    4513: [Sdoi2016]储能表

    链接

    分析:

      数位dp。

      横坐标和纵坐标一起数位dp,分别记录当前横纵坐标中这一位是否受n或m的限制,在记录一维表示当前是否已经大于k了。

      然后需要两个数组记录答案,分别记录个数和答案的和。

      语意不清了。。。看代码吧。。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<cctype>
    #include<set>
    #include<vector>
    #include<queue>
    #include<map>
    #define fi(s) freopen(s,"r",stdin);
    #define fo(s) freopen(s,"w",stdout);
    using namespace std;
    typedef long long LL;
    
    inline LL read() {
        LL x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 1005;
    int a[N], b[N], c[N], c1, c2, c3, Cnt;
    LL dp[N][2][2][2], mi[N], cnt[N][2][2][2], n, m, k, p;
    #define pa pair<LL,LL>
    
    pa dfs(int x,LL now,bool l1,bool l2,bool l3) {
        if (!x) { return pa((-k + p) % p, 1); }
        if (dp[x][l3][l1][l2]) return pa(dp[x][l3][l1][l2], cnt[x][l3][l1][l2]);
        int u1 = l1 ? a[x] : 1;
        int u2 = l2 ? b[x] : 1;
        LL res = 0, sum = 0;
        for (int i = 0; i <= u1; ++i) 
            for (int j = 0; j <= u2; ++j) {
                int t = i ^ j;
                if (l3 && t < c[x]) continue;
                pa tmp = dfs(x - 1, t ? now + mi[x - 1] : now, l1 && i == u1, l2 && j == u2, l3 && t == c[x]);
                res += (tmp.first + tmp.second * t * mi[x - 1] % p) % p;
                sum += tmp.second;
                res %= p;
                sum %= p;
            }
        dp[x][l3][l1][l2]= res, cnt[x][l3][l1][l2] = sum;
        return pa(res, sum);
    }
    void Calc() {
        n --, m --;
        c1 = c2 = c3 = Cnt = 0;
        LL t = n; 
        while (t) a[++c1] = t % 2, t /= 2;
        t = m; 
        while (t) b[++c2] = t % 2, t /= 2;
        t = k;
        while (t) c[++c3] = t % 2, t /= 2;
        Cnt = max(c1, max(c2, c3));
        cout << dfs(Cnt, 0, 1, 1, 1).first << "
    ";
        for (int i = 0; i <= Cnt; ++i) a[i] = b[i] = c[i] = 0;
        memset(dp, 0, sizeof(dp));
        memset(cnt, 0, sizeof(cnt));
    }
    void solve() {
        n = read(), m = read(), k = read(), p = read();
        mi[0] = 1;
        for (int i = 1; i <= 100; ++i) mi[i] = mi[i - 1] * 2 % p;
        Calc();
    }
    int main() {
        for (int T = read(); T --; solve());    
        return 0;
    }
  • 相关阅读:
    dojo grid 组件
    在xpage开发的时候出现xsp is not defined的错误
    关于Xpages中ssjs库相互引用的问题
    Xpages下实现输入智能提示(TypeAhead)功能
    Xpage中对定制控件在设计视图下外观的定制
    xpage中关于dojo版本的配置
    数据库查询优化方案
    查询表结构
    经典SQL语句集锦
    c#导出PDF
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10392337.html
Copyright © 2011-2022 走看看