4513: [Sdoi2016]储能表 数位DP

国际惯例的题面:

听说这题的正解是找什么规律,数位DP是暴力......
好的,我就写暴力了QAQ。
我们令f[i][la][lb][lc]表示二进制从高到低考虑位数为i(最低位为1),是否顶n上界,是否顶m上界,是否顶k下界的数字和,g[i][la][lb][lc]表示(同上定义)的数字个数。
转移的话,先计算出这一位n,m,k的限制,然后枚举这一位第一个数和第二个数填什么,判定xor和是否满足k的条件,转移即可。
记忆化搜索实现较为简单。
注意最后计算答案的时候,方案数乘以k可能爆long long,所以k要先取模。

代码:
(就算我WA了,TLE了,代码写的像屎一样,也不include<iostream>!pair真好用。)

 1 #include<cstdio>
 2 #include<algorithm> 
 3 #include<cstring>
 4 typedef long long int lli;
 5 const int maxn=1e2+1e1;
 6 
 7 lli f[maxn][2][2][2],g[maxn][2][2][2]; // f is sum , g is count .
 8 int ba[maxn],bb[maxn],bc[maxn],mod;
 9 
10 inline void dfs(int bit,int la,int lb,int lc) { // bit is the bit that we are determining in range [1,64] .
11     if( ~f[bit][la][lb][lc] ) return;
12     if( !bit ) {
13         f[bit][la][lb][lc] = 0 , g[bit][la][lb][lc] = 1;
14         return;
15     } int lima = !la || ba[bit] , limb = !lb || bb[bit] , limc = lc && bc[bit];
16     f[bit][la][lb][lc] = g[bit][la][lb][lc] = 0;
17     for(int i=0;i<=lima;i++) for(int j=0;j<=limb;j++) if( ( i ^ j ) >= limc ) {
18         int ta = la&&i==lima , tb = lb&&j==limb , tc = lc&&(i^j)==limc;
19         dfs(bit-1,ta,tb,tc);
20         g[bit][la][lb][lc] = ( g[bit][la][lb][lc] + g[bit-1][ta][tb][tc] ) % mod ,
21         f[bit][la][lb][lc] = ( f[bit][la][lb][lc] + f[bit-1][ta][tb][tc] + ( (lli) ( i ^ j ) << ( bit -  1 ) ) % mod * g[bit-1][ta][tb][tc] % mod ) % mod;
22     }
23 }
24 
25 inline int cutbit(lli t,int* dst) {
26     int ret = 0; memset(dst,0,sizeof(int)*maxn);
27     while(t) dst[++ret] = t & 1 , t >>= 1;
28     return ret;
29 }
30 
31 int main() {
32     static int T,mx;
33     static lli n,m,k,ans;
34     scanf("%d",&T);
35     while(T--) {
36         scanf("%lld%lld%lld%d",&n,&m,&k,&mod) , --n , --m , memset(f,-1,sizeof(f)) , memset(g,0,sizeof(g)) , mx = std::max( cutbit(k,bc) , std::max( cutbit(n,ba) , cutbit(m,bb) ) ) ,
37         dfs(mx,1,1,1) , ans = (f[mx][1][1][1]-g[mx][1][1][1]*(k%mod)%mod+mod)%mod , printf("%lld\n",ans);
38     }
39     return 0;
40 }
View Code



く遠く続いてる 空
遥远地 遥远地 无尽延伸的天空
その向こうで 君は 何想う
彼方的你 现在正想些什么
いつか消える あの星の下
在那颗终会陨落的星星下
永遠(とわ)を願い 想い見上げ
翘首仰望着 祈求着永恒

強く弱く光を放つ
灿烂的 黯淡的 明灭闪耀的星光
君の近くに 北斗七星
在你身边的 北斗七星
そんな 輝きであるように
我想像它一样照耀着你
君を想い 願い掛けて
思念着你 许下了愿望

posted @ 2018-05-03 23:27  Cmd2001  阅读(264)  评论(0编辑  收藏  举报