Logo Wy Online Judge

WyOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#541#115. 【0621 模拟赛】Bojanjelxn10084ms3696kbC++143.2kb2025-06-20 16:41:272025-06-21 23:21:19

answer

/*
题解:
学习收获:DP状态的设计与压缩。
状态和细节很多的一个题目
nk很小。之和颜色数有关,合并颜色 ,n=10,可能的颜色数有多少,实际是一个正数划分问题
以 n=5为例,可能的颜色方案为
1:1 1 1 1 1
2:1 1 1 2
3:1 1 3
4:1 2 2
5:1 4
6:2 3
7:5
共有7种状态。n=10可以计算出共有43种。设有m种状态。 
在m种专题之间构图,建立转移矩阵,有自环。 
1->2
2->3
3->4 
4->3
....

 
从初始状态1,计算走T步到达各个点的概率是多少。把大于k的节点的概率值相加。 
重点,找出状态数有多少,计算状态之间转移的概率值。 

*/ 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#define ll long long
using namespace std;
const int MOD = 1e9 + 7;
map<vector<int>, int> mp;
map<int, vector<int> > gt;
int n, k;
ll t;
vector<int> mat4;
int tq = 0;
void dfs(vector<int> vec, int fin, int sum) {//dfs处理数的划分,找出所有的划分状态。设立二者的一一对应。 
    if(sum == n) {
        mp[vec] = ++tq;
        gt[tq] = vec;
        //cout << tq << " " << endl;
        //for(int i = 0; i < vec.size(); i++) cout << vec[i] << " ";
        //cout << endl;
        return;
    }
    for(int i = fin; i <= n; i++) {
        if(sum + i <= n) {
            vec.push_back(i);
            dfs(vec, i, sum + i);
            vec.pop_back();
        }
    }
}
struct matrix {
    int num[43][43];
} zero;
matrix operator*(matrix p1, matrix p2) {
    matrix res = zero;
    for(int i = 1; i <= tq; i++) {
        for(int j = 1; j <= tq; j++) {
            for(int k = 1; k <= tq; k++) {
                res.num[i][j] += (ll)p1.num[i][k] * p2.num[k][j] % MOD;
                res.num[i][j] %= MOD;
            }
        }
    }
    return res;
}
int ksm(int x, int y) {
    if(y <= 1) return y ? x : 1;
    int ktm = ksm(x, y >> 1);
    return (ll)ktm * ktm % MOD * ((y & 1) ? x : 1) % MOD;
}
int main() {
    scanf("%d%lld%d", &n, &t, &k);
    dfs(mat4, 1, 0);
    matrix mat2 = zero;
    for(int fm = 1; fm <= tq; fm++) {//计算状态之间的转移关系,数据都没有除n*n 
        vector<int> vec = gt[fm];
        for(int pi = 0; pi < vec.size(); pi++) {
            for(int pj = 0; pj < vec.size(); pj++) {
                vector<int> ec = vec;
                ec[pi]++;
                ec[pj]--;//mat3, mat4
                if(ec[pj] == 0) swap(ec[pj], ec[ec.size() - 1]), ec.pop_back();
                sort(ec.begin(), ec.end());
                mat2.num[fm][mp[ec]] += vec[pi] * vec[pj];
            }
        }
    }
    matrix mat3 = zero;
    mat3.num[1][1] = 1;//从1点开始,矩阵快速幂。 
    matrix mat1 = mat2;
    while(t) {
        if(t & 1) mat3 = mat3 * mat1;
        mat1 = mat1 * mat1, t >>= 1;
    }
    int ansp, ansq;
    ansp = ansq = 0;
    for(int ek = 1; ek <= tq; ek++) {
        if(gt[ek].size() >= k) ansp += mat3.num[1][ek], ansp %= MOD;//符合要求的状态
        ansq += mat3.num[1][ek], ansq %= MOD;//所有的状态
    }
    printf("%d\n", (int)((ll)ansp * ksm(ansq, MOD - 2) % MOD));//求概率。
    return 0;
}

Details

小提示:点击横条可展开更详细的信息

Subtask #1:

score: 28
Accepted

Test #1:

score: 28
Accepted
time: 1ms
memory: 3444kb

input:

8 1 8

output:

125000001

result:

ok "125000001"

Test #2:

score: 0
Accepted
time: 1ms
memory: 3448kb

input:

9 2 9

output:

123456791

result:

ok "123456791"

Test #3:

score: 0
Accepted
time: 0ms
memory: 3556kb

input:

2 298410478936087415 2

output:

570941114

result:

ok "570941114"

Test #4:

score: 0
Accepted
time: 0ms
memory: 3664kb

input:

5 576602506791120693 5

output:

624640657

result:

ok "624640657"

Test #5:

score: 0
Accepted
time: 29ms
memory: 3684kb

input:

10 256228184114116456 10

output:

325844394

result:

ok "325844394"

Subtask #2:

score: 36
Accepted

Test #6:

score: 36
Accepted
time: 0ms
memory: 3560kb

input:

5 2 3

output:

1

result:

ok "1"

Test #7:

score: 0
Accepted
time: 1ms
memory: 3696kb

input:

3 565 2

output:

446411373

result:

ok "446411373"

Test #8:

score: 0
Accepted
time: 2ms
memory: 3696kb

input:

8 377 3

output:

121415859

result:

ok "121415859"

Test #9:

score: 0
Accepted
time: 1ms
memory: 3384kb

input:

9 840 8

output:

165318551

result:

ok "165318551"

Test #10:

score: 0
Accepted
time: 5ms
memory: 3520kb

input:

10 936 4

output:

611789290

result:

ok "611789290"

Subtask #3:

score: 36
Accepted

Test #11:

score: 36
Accepted
time: 1ms
memory: 3596kb

input:

6 607026166077649625 5

output:

312920168

result:

ok "312920168"

Test #12:

score: 0
Accepted
time: 1ms
memory: 3520kb

input:

7 125452864890658981 2

output:

815023468

result:

ok "815023468"

Test #13:

score: 0
Accepted
time: 3ms
memory: 3424kb

input:

8 511066077813606532 4

output:

283063302

result:

ok "283063302"

Test #14:

score: 0
Accepted
time: 12ms
memory: 3696kb

input:

9 570632528518075962 5

output:

348914172

result:

ok "348914172"

Test #15:

score: 0
Accepted
time: 27ms
memory: 3672kb

input:

10 294082151269059690 8

output:

69248946

result:

ok "69248946"