BZOJ 4513: [Sdoi2016]储能表

Description

求\(\sum_{i=0}^{n-1}\sum_{i=0}^{n-1}max\{i\)^\(j-k,0\}\)

\(n,m\leqslant 10^{18},k\leqslant 10^9\)

Solution

数位DP。

我好弱啊qwq...

\(f[i][na][nb][nc]\)表示枚举到第\(i\)位,是否卡\(n\)上界,是否卡\(m\)上界,是否卡\(k\)下界。

枚举\(i\)这一位01,\(j\)这一位01,枚举上一个状态,判断一下合法,计算转移后的状态,统计。

最后答案就是\(f[0][0][0][0]\),这样正好小于n,m和大于k。

Code

/**************************************************************
    Problem: 4513
    User: BeiYu
    Language: C++
    Result: Accepted
    Time:7048 ms
    Memory:1300 kb
****************************************************************/

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 70;

inline LL in(LL x=0,char ch=getchar()) { while(ch>‘9‘ || ch<‘0‘) ch=getchar();
    while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();return x; }

LL T,n,m,k,p;
LL pw[N],f[N][2][2][2],g[N][2][2][2];
void Add(LL &x,LL y) { x=(x+y%p)%p; }

int main() {
    for(T=in();T--;) {
        n=in(),m=in(),k=in(),p=in();
        memset(f,0,sizeof(f)),memset(g,0,sizeof(g));
        for(int i=0;i<N;i++) pw[i]=(1LL<<i)%p;
        g[63][1][1][1]=1;
        for(int i=62;~i;--i) {
            int a=(n>>i)&1,b=(m>>i)&1,c=(k>>i)&1;
            for(int xx=0;xx<2;xx++) for(int yy=0;yy<2;yy++) {
                int zz=xx^yy;
                for(int aa=0;aa<2;aa++) for(int bb=0;bb<2;bb++)
                    for(int cc=0;cc<2;cc++) {
                        if(aa && xx>a) continue;
                        if(bb && yy>b) continue;
                        if(cc && zz<c) continue;
                        int na=aa?(xx==a):0,nb=bb?(yy==b):0,nc=cc?(zz==c):0;
                        Add(f[i][na][nb][nc],f[i+1][aa][bb][cc]+((LL)zz-c+p)*pw[i]%p*g[i+1][aa][bb][cc]%p);
                        Add(g[i][na][nb][nc],g[i+1][aa][bb][cc]);
                    }
            }
        }printf("%lld\n",f[0][0][0][0]);
    }return 0;
}

  

时间: 2025-01-04 12:02:48

BZOJ 4513: [Sdoi2016]储能表的相关文章

4513: [Sdoi2016]储能表

4513: [Sdoi2016]储能表 链接 分析: 数位dp. 横坐标和纵坐标一起数位dp,分别记录当前横纵坐标中这一位是否受n或m的限制,在记录一维表示当前是否已经大于k了. 然后需要两个数组记录答案,分别记录个数和答案的和. 语意不清了...看代码吧.. 代码: #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<iostream>

搜索(四分树):BZOJ 4513 [SDOI2016 Round1] 储能表

4513: [Sdoi2016]储能表 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 395  Solved: 213[Submit][Status][Discuss] Description 有一个 n 行 m 列的表格,行从 0 到 n−1 编号,列从 0 到 m−1 编号.每个格子都储存着能量.最初,第 i 行第 j 列的格子储存着 (i xor j) 点能量.所以,整个表格储存的总能量是, 随着时间的推移,格子中的能量会渐渐减少.一个时间

【bzoj4513】[Sdoi2016]储能表 数位dp

我真TM是个sb!!! f[i][0/1][0/1][0/1]表示考虑到第i位前i位是否卡n的上界,是否卡m的上界,是否卡k的下界的数对的个数 g[i][0/1][0/1][0/1]表示考虑到第i位前i位是否卡n的上界,是否卡m的上界,是否卡k的下界的数对的和 直接dp #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #

[SDOI2016]储能表

题目 数位\(dp\)思博题啊 但是我更加思博啊 面对\(10^{18}\)的数据范围,我竟然只开了\(19\)的数据,而这是一道二进制数位\(dp\)啊 我们设\(f[i][0/1][0/1][0/1]\)表示进行到了第\(i\)位,不卡/卡\(n\)的上界,不卡/卡\(m\)的上界,不卡/卡\(k\)的下界,我们求出所有异或值大于\(k\)的数的和,和方案数随便搞一搞就出来了 代码 #include<algorithm> #include<iostream> #include&

bzoj 4513 储能表

一句话题面 ∑x=0n?1∑y=0m?1min(x⊕y?k,0)(modp) 好的题面就到这里 数位dp一下就好 记忆话搜索的时候其实用不着很多的分类讨论,具体的看代码吧 #include<bits/stdc++.h> using namespace std; #define LL long long const int maxn = 70; LL n[maxn],m[maxn],k[maxn]; LL p; LL cnt[maxn][2][2][2],dp[maxn][2][2][2]; L

loj2030 「SDOI2016」储能表

ref ref 一个点就是一个数对 \((x,y)\). 记状态 \(f[i][1/0][1/0][1/0]\) 和 \(g[i][1/0][1/0][1/0]\),其中三个 \(1/0\) 取值分别代表"\(x\) 在前 \(i\) 位卡满 \(n\)(的前 \(i\) 位)/小于它"."\(y\) 在前 \(i\) 位卡满 \(m\)(的前 \(i\) 位)/小于它"."\(k_{current}\) 在前 \(i\) 位卡满 \(k\)(的前 \(i

BZOJ 4517: [Sdoi2016]排列计数 错排+逆元

4517: [Sdoi2016]排列计数 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m 个数是稳定的 满足条件的序列可能很多,序列数对 10^9+7 取模. Input 第一行一个数 T,表示有 T 组数据. 接下来 T 行,每行两个整数 n.m. T=500000,n≤1000000,m≤1000000 Output 输出 T 行,每行一个数,表示

图论(费用流):BZOJ 4514 [Sdoi2016]数字配对

4514: [Sdoi2016]数字配对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 820  Solved: 345[Submit][Status][Discuss] Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci×cj 的价值. 一个数字只能参与一次配对,可以不参与配对. 在

数学(错排):BZOJ 4517: [Sdoi2016]排列计数

4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 693  Solved: 434[Submit][Status][Discuss] Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m 个数是稳定的 满足条件的序列可能很多,序列数对 10^9+7 取模. Input 第