1423 J Bubble Cup hypothesis
Solution 1 : DP
这个做法不想多讲,毕竟是过不去的。但是可能可以用于更广的 c i c_i ci取值。
大概就是 d p i , j dp_{i,j} dpi,j表示 c i c_i ci需要是 j j j的方案数,其中 c i c_i ci可以分配一些到后面处理。
时间复杂度 O ( log 2 m ∗ K ) O(\log_2m*K) O(log2m∗K)的。 K K K表示 c i c_i ci要 ≤ K \leq K ≤K。
不过这题有 5 e 5 5e5 5e5个数据,且卡 1 s 1s 1s,所以不太好卡过去。(但是仍然有不少神仙用dp的这个做法过了,具体的可以看看code里 900 m s + 900ms+ 900ms+的代码)
这里放上我的巨慢代码(4s+)
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
int vis[15][62];
int dp[15][62];
const int MOD=1e9+7;
LL m;
int t;
inline int calc(int j,int i){
if(j==0){
return dp[i][j]=(i<=7);
}
if(vis[i][j]==t) return dp[i][j];
vis[i][j]=t;
dp[i][j]=0;
int addition=((m>>(j-1))&1ll);
if(i==0){
dp[i][j]=calc(j-1,addition);
}
else{
dp[i][j]=calc(j,i-1);
if(i>7){
int k=i-7-1;
if(k+k+addition<=14)
dp[i][j]+=MOD-calc(j-1,k+k+addition);
if(dp[i][j]>=MOD) dp[i][j]-=MOD;
}
int k=i;
if(k+k+addition<=14)
dp[i][j]+=calc(j-1,k+k+addition);
if(dp[i][j]>=MOD) dp[i][j]-=MOD;
}
return dp[i][j];
}
int main(){
scanf("%d",&t);
while(1){
scanf("%I64d",&m);
printf("%d\n",calc(61,0));
t--;
if(t==0) break;
}
return 0;
}
Solution 2 : 数学
P ( x ) = c 0 + c 1 x . . . + c n x n + . . . = ( c 0 + 8 ∗ c 3 + 64 ∗ c 6 . . . ) + 2 ∗ ( c 1 + 8 ∗ c 4 . . . ) + 4 ∗ ( c 2 + 8 ∗ c 5 ) P(x)=c_0+c_1x...+c_nx^n+...=(c_0+8*c_3+64*c_6...)+2*(c_1+8*c_4...)+4*(c_2+8*c_5) P(x)=c0+c1x...+cnxn+...=(c0+8∗c3+64∗c6...)+2∗(c1+8∗c4...)+4∗(c2+8∗c5)
P ( x ) = x + 2 ∗ y + 4 ∗ z P(x)=x+2*y+4*z P(x)=x+2∗y+4∗z
一个数 x x x与 c 0 + 8 ∗ c 1 + . . . 8 k ∗ c k + . . . c_0+8*c_1+...8^k*c_k+... c0+8∗c1+...8k∗ck+...是一一对应的( c 0 c 1 c 2 . . c_0c_1c_2.. c0c1c2..)是 x x x的8进制。
方程 x + 2 y = m x+2y=m x+2y=m的解的个数= ⌊ m 2 ⌋ + 1 \huge{\left \lfloor \frac{m}2 \right \rfloor+1} ⌊2m⌋+1
则
A
n
s
=
∑
i
=
0
⌊
m
4
⌋
(
⌊
m
−
4
i
2
⌋
+
1
)
=
∑
i
=
0
⌊
m
4
⌋
(
⌊
m
2
⌋
−
2
z
+
1
)
=
(
⌊
m
4
⌋
+
1
)
(
⌊
m
2
⌋
−
⌊
m
4
⌋
+
1
)
Ans=\sum _{i=0}^{\left \lfloor\frac{m}{4}\right \rfloor} (\left \lfloor \frac{m-4i}2 \right \rfloor+1)=\sum _{i=0}^{\left \lfloor \frac{m}4 \right \rfloor}(\left \lfloor \frac{m}2 \right \rfloor-2z+1)=(\left \lfloor \frac{m}4 \right \rfloor+1)(\left \lfloor \frac{m}2 \right \rfloor-\left \lfloor \frac{m}4 \right \rfloor+1)
Ans=i=0∑⌊4m⌋(⌊2m−4i⌋+1)=i=0∑⌊4m⌋(⌊2m⌋−2z+1)=(⌊4m⌋+1)(⌊2m⌋−⌊4m⌋+1)
这样就可以
O
(
1
)
O(1)
O(1)算了。