1 条题解

  • 0
    @ 2026-2-27 16:29:15
    #include <bits/stdc++.h>
    using namespace std;
    
    int t; // [1] t-测试数据总组数
    int arr[100100]; // [2] arr-存储所有器材价格的全局数组
    
    // 计算长度为m的链的独立集数目
    long long countChain(int m) { // [21] m-传入的当前链长度
        if (m == 1) return 2; // [22] 边界判断:1个节点的独立集数
        if (m == 2) return 3; // [23] 边界判断:2个节点的独立集数
        long long a = 2, b = 3; // [24] a=f(m-2), b=f(m-1)-递推滚动变量
        // [25] 从第3项开始递推求独立集数
        for (int i = 3; i <= m; ++i) {
            long long c = a + b; // 计算当前项
            a = b; // 滚动更新前前项
            b = c; // 滚动更新前项
        }
        return b; // 返回长度为m的链的独立集总数
    }
    
    int main(){
        cin >> t; // [3] 读取测试数据总组数
        // [4] 循环处理每一组测试数据
        while(t--)
        {
            int n , k; // [5] n-当前组器材总数,k-禁止的价格差
            cin >> n >> k; // [6] 读取当前组的n和k
    
            // [7] 读取当前组n个器材的价格
            for(int i = 1;i <=n ;i++) cin >> arr[i];
    
            sort(arr + 1 , arr + n + 1); // [8] 对当前组价格数组升序排序
    
            vector<vector<int>> dp(k); // [9] dp-按模k余数分组的二维容器
    
            // [10] 将当前组所有器材按价格模k余数归类
            for(int i = 1;i <=n ;i++)
            {
                int r = arr[i] % k; // [11] r-当前价格模k的余数
                dp[r].push_back(arr[i]); // [12] 将价格放入对应余数的分组
            }
    
            long long ans = 1; // [13] ans-当前组最终答案,初始化为1用于累乘
            // [14] 遍历每个余数分组,计算总方案数
            for(int i = 0;i < k ;i++)
            {
                if(dp[i].empty()) continue; // [15] 跳过无元素的空分组
                int len = 1; // [16] len-当前连续链的长度
                // [17] 遍历分组内元素,拆分出所有独立的链
                for(int j = 1;j < dp[i].size() ;j++)
                {
                    // [18] 相邻元素差为k,属于同一条链
                    if(dp[i][j] - dp[i][j-1] == k){
                        len++; // 链长加1
                    }
                    // [19] 链断裂,计算前一段链的贡献
                    else{
                        ans *= countChain(len); // 累乘当前链的方案数
                        len = 1; // 重置链长为1
                    }
                }
                ans *= countChain(len); // [20] 累乘分组内最后一条链的方案数
            }
    
            cout << ans << endl; // [26] 输出当前组的答案
        }
        return 0;
    }
    

    信息

    ID
    1474
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者