Luogu2481 SDOI 2010 코드 경매 DP, 콤보
신선DP
\(N\leq 10^ {18}\) 를 알아차리면 직접 디지털 DP를 사용할 수 없기 때문에 형성된\(N\) 비트의 성질을 고려합니다.
낮은 비트는 높은 비트보다 작지 않으므로 조건에 맞는 모든\(N\) 비트는\(9\)개\(f(x)(x\in[1,N])\)의 합을 초과하지 않으며 여기서\(f(x)=\sum\limits{i=0}^{x-1}10^i\), 그리고 그 중에는 반드시\(f (N)\) 가 있습니다.
\(f (x)\\bmod\P\) 로 이루어진 수열을 고려합니다.\(f (x) = 10f (x-1) + 1\) 이기 때문에 이 수열에는\(P\) 를 초과하지 않는 순환절이 반드시 존재합니다.그러면 이 예처리를 통해\(cnt i =\sum\limits {x=1}^N[f(x)\mod P = i]\) 를 미리 처리하고\(f(N)\\\bmod\P\) 의 값을 구할 수 있습니다.
다음에 DP를 사용할 수 있습니다. 설정\(f {i, j, k}\) 는\(cnt 0\sim cnt {i-1}\) 를 고려하고\(k\) 개\(f (x)\) 를 선택했습니다. 그것들의 합\(\bmod\P = j\) 방안 수입니다.이동은 열거\(cnt i\) 중 몇 개를 선택해야 하는지를 고려한다. 이것이 바로 삽입법이고 이동 계수는 하나의 조합수이다.
마지막 답은\(\sum\limits {i=0}^8 f {P,(P-f(N))\\bmod P,i}\)입니다.\(i\)가 최대\(8\)인 이유는\(f(n)\)를 선택해야 하기 때문입니다.
#include
using namespace std;
#define int long long
const int MOD = 999911659;
int dp[503][503][9] , Cnt[503] , dir[503] , N , P;
int poww(int a , int b){
int times = 1;
while(b){
if(b & 1) times = times * a % MOD;
a = a * a % MOD; b >>= 1;
}
return times;
}
int binom(int a , int b){
int times = 1;
for(int i = a ; i > a - b ; --i)
times = times * i % MOD * poww(a - i + 1 , MOD - 2) % MOD;
return times;
}
signed main(){
cin >> N >> P;
int cur = 1 % P , cnt = 1 , tmp = 1 % P , ed;
do{dir[cur] = cnt; ++cnt; cur = (cur * 10 + 1) % P;}while(!dir[cur]);
for(int i = 1 ; i < dir[cur] && i <= N ; ++i , tmp = (tmp * 10 + 1) % P) ++Cnt[ed = tmp];
if(dir[cur] <= N){
for(int i = dir[cur] ; i < cnt ; ++i , tmp = (tmp * 10 + 1) % P) Cnt[ed = tmp] = (N - dir[cur] + 1) / (cnt - dir[cur]) % MOD;
for(int i = 1 ; i <= (N - dir[cur] + 1) % (cnt - dir[cur]) ; ++i , tmp = (tmp * 10 + 1) % P) ++Cnt[ed = tmp];
}
dp[0][0][0] = 1;
for(int i = 0 ; i < P ; ++i)
for(int j = 0 ; j <= 8 ; ++j){
int val = binom(Cnt[i] + j - 1 , j);
if(!val) continue;
for(int k = 0 ; k < P ; ++k)
for(int l = 0 ; l + j <= 8 ; ++l)
dp[i + 1][(k + i * j) % P][l + j] = (dp[i + 1][(k + i * j) % P][l + j] + val * dp[i][k][l]) % MOD;
}
int sum = 0;
for(int i = 0 ; i <= 8 ; ++i)
sum = (sum + dp[P][(P - ed) % P][i]) % MOD;
cout << sum;
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.