QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#301115#7895. Graph Partitioning 2luyiming123WA 19ms11200kbC++144.6kb2024-01-09 14:42:052024-01-09 14:42:06

Judging History

你现在查看的是最新测评结果

  • [2024-01-09 14:42:06]
  • 评测
  • 测评结果:WA
  • 用时:19ms
  • 内存:11200kb
  • [2024-01-09 14:42:05]
  • 提交

answer

# include <bits/stdc++.h>
using namespace std;
using i64 = long long; 
const int N = 1e5 + 5; 
const i64 mod = 998244353; 
void Add(i64 &x, i64 y) {x = (x + y) % mod; if(x < 0) x += mod; return; }
int n, k; 
vector <int> g[N]; 
i64 dp[N][(int)sqrt(N) + 5], tmp[(int)sqrt(N) + 5];
int siz[N];  

namespace subtask1 // k <= sqrtn
{
    void dfs(int x, int fa)
    {
        dp[x][1] = 1; siz[x] = 1; 
        for(int v : g[x])
        {
            if(v == fa) continue; 
            dfs(v, x); 
            for(int i = 1; i <= min(k + 1, siz[x]); i++) tmp[i] = dp[x][i], dp[x][i] = 0; 
            for(int i = 1; i <= min(k + 1, siz[x] + siz[v]); i++)
            {
                for(int j = 1; j <= min(k + 1, siz[v]); j++)
                {
                    //link
                    if(j <= i && i - j <= min(k + 1, siz[x])) Add(dp[x][i], dp[v][j] * tmp[i - j] % mod); 
                    // printf("j = %d, dp[%d][%d] <- %lld * %lld\n", j, x, i, dp[v][j], tmp[i - j]); 
                    //cut
                    if((j == k || j == k + 1) && i <= min(k + 1, siz[x])) Add(dp[x][i], dp[v][j] * tmp[i] % mod); 
                    // printf("j = %d, dp[%d][%d] <-- %lld * %lld, sizx = %d\n", j, x, i, dp[v][j], tmp[i], siz[x]); 
                }
            }
            siz[x] += siz[v]; 
        }
        // for(int i = 1; i <= min(k + 1, siz[x]); i++)
        //     printf("dp[%d][%d] = %lld\n", x, i, dp[x][i]); 
        return; 
    }

    void Main(void)
    {
        for(int i = 1; i <= n; i++)
            for(int j = 0; j <= k + 1; j++) dp[i][j] = 0; 
        
        dfs(1, 0); 
        printf("%lld\n", (dp[1][k] + dp[1][k + 1]) % mod); 
    }
}

namespace subtask2 // k > sqrtn
{

    void dfs(int x, int fa)
    {
        dp[x][0] = 1, siz[x] = 1; 
        for(int v : g[x])
        {
            if(v == fa) continue; 
            dfs(v, x); 
            int limx = (siz[x] + siz[v]) / k, limv = siz[v] / k; 
            for(int i = 0; i <= limx; i++) tmp[i] = dp[x][i], dp[x][i] = 0; 
            for(int i = 0; i <= limx; i++)
            {
                // int bx = (siz[x] + siz[v]) - i * k; 
                // bx %= (k + 1); if(!bx) bx = k + 1; 
                for(int j = 0; j <= min(limv, i); j++)
                {
                    int bv = siz[v] - j * k; 
                    bv %= (k + 1); if(!bv) bv = k + 1;
                    if(j <= i)
                    {
                        int bx = siz[x] - (i - j) * k; 
                        bx %= (k + 1); if(!bx) bx = k + 1; 
                        if(bx + bv <= k + 1)
                        {
                            Add(dp[x][i], dp[v][j] * tmp[i - j] % mod); 
                            // printf("i = %d, j = %d, bx = %d, bv = %d, dp[%d][%d] <- %lld * %lld\n", i, j, bx, bv, x, i, dp[v][j], tmp[i - j]); 
                        }
                    }

                    // if(bv == k || bv == k + 1) 
                    // {
                    //     Add(dp[x][i], dp[v][j] * tmp[i] % mod), 
                    //     printf("i = %d, j = %d, bv = %d, dp[%d][%d] <-- %lld * %lld\n", i, j, bv, x, i, dp[v][j], tmp[i]); 
                    // }
                    if(bv == k && i - j - 1 >= 0)
                    {
                        Add(dp[x][i], dp[v][j] * tmp[i - j - 1] % mod); 
                    }
                    else if(bv == k + 1 && j <= i)
                    {
                        Add(dp[x][i], dp[v][j] * tmp[i - j] % mod); 
                    }
                }
            }
            siz[x] += siz[v]; 
        }
        // for(int i = 0; i <= siz[x] / k; i++) 
        //     printf("dp[%d][%d] = %lld\n", x, i, dp[x][i]);
        return; 
    }

    void Main(void)
    {
        for(int i = 1; i <= n; i++)
        {
            for(int j = 0; j <= (n / k) + 5; j++) dp[i][j] = 0; 
        }
        dfs(1, 0); 
        i64 Ans = 0; 
        for(int x = 0; x <= (n / k) + 5; x++) 
        {
            int vt = (n - x * k) % (k + 1); 
            if(vt == k || vt == 0) Add(Ans, dp[1][x]); 
        }
        printf("%lld\n", Ans); 
        return; 
    }
}

int main(void)
{
    int Test; scanf("%d", &Test); 
    while(Test--)
    {
        scanf("%d%d", &n, &k); 
        for(int i = 1; i <= n; i++) g[i].clear(); 
        for(int i = 1; i < n; i++)
        {
            int u, v; scanf("%d%d", &u, &v); 
            g[u].push_back(v), g[v].push_back(u); 
        }
        if(1ll * k * k <= n) subtask1 :: Main(); 
        else subtask2 :: Main(); 
    }
    return 0; 
}

详细

Test #1:

score: 100
Accepted
time: 2ms
memory: 6776kb

input:

2
8 2
1 2
3 1
4 6
3 5
2 4
8 5
5 7
4 3
1 2
1 3
2 4

output:

2
1

result:

ok 2 lines

Test #2:

score: -100
Wrong Answer
time: 19ms
memory: 11200kb

input:

5550
13 4
10 3
9 1
10 8
3 11
8 5
10 7
9 6
13 5
9 7
2 7
5 12
4 8
8 2
4 1
3 4
7 8
2 5
6 7
4 8
2 3
11 1
11 10
1 4
9 10
8 4
3 6
5 7
6 1
10 2
11 7
11 1
17 2
14 16
13 15
17 3
15 11
1 6
13 2
13 17
4 8
14 10
8 14
14 5
9 12
14 2
12 17
17 6
15 7
14 6
2 14
2 13
2 4
8 4
3 11
7 3
14 1
11 9
13 3
5 10
6 8
3 10
14 ...

output:

0
93
3001
2082
1
6156
88
43
0
0
49
0
1
0
0
1
23
5932
0
234
0
145644
1
272
778
1
859
2
0
50094
0
1
0
0
0
1
1
48
0
4001
754987
2260
0
195486
70
0
1
0
39539
1
661695
459233
171
1118
0
1
0
46
0
0
0
0
0
297
0
0
0
1
0
1
1
1
8668
605
0
0
1
0
0
0
36
0
1
0
0
1
1
46
49
0
1
0
0
0
895
0
225
105
130
0
72
21470
0...

result:

wrong answer 2nd lines differ - expected: '3', found: '93'