题解 CF1876B

题意

给定一个数组 [a1,a2,a3.,an],一开始所有元素都为白色。你可以选定其中的至少一个元素涂成黑色,共有 2n1 种涂法。此时对于所有黑色元素 ai , 下标为 i 的倍数的所有白色元素都将变成绿色。此时数组中所有黑色和绿色元素的最大值记为此种涂法的分数。

问对于所有 an1 种涂法,每种涂法的分数之和为多少?

题解

我们考虑涂一个黑色元素 ai,记所有下标为 i 倍数的元素最大值为 aimax。所有包含涂 ai 的方法共有 2n1 种。但是这些方案中还可能涂了其他的黑色元素 aj,使得 ajmax>aimax,所以计算 ai 的贡献中还要剔除掉这些分数比 aimax 大的方案数。

所以我们可以反着考虑,计算分数为 ai 时的贡献。先将数组从大到小排序。ai 作为方案的分数当且仅当 i 是某个黑色元素的下标倍数,所以我们枚举 i 的所有因数 k。如果 k 之前被更大的 aj 枚举过,那么涂 ak 的方案的分数肯定是 aj,不能记到分数为 ai 的贡献里。如果 k 未被枚举过,那么此时 分数为 ai 且涂了 ak 的方案 的贡献为 所有包含 ak 且不包含枚举过的数的方案数ai(包含枚举过的数的方案,之前记过更大的分数)。

开一个标记数组标记枚举过的因数。将 a 数组从大到小排序。逐个考虑每一个 ai 的所有因数,同时记录此时 1n 中还未被标记的数的个数 t

  1. 统计未被标记的因数个数 b,并标记这些因数。

  2. 记录 ai 的贡献为 cai=aij=1b2tj,再将 tb

所有包含 ak 且不包含枚举过的数的方案数 即为其中的 2tj。这是因为此时还未标记的数还有 tj 个,而真子集一共有 2tj 种。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 100010
#define MOD 998244353
#define REP(a, b, i) for(int i = (a); i <= (b); i++)

ll dn[MAXN];
bool vis[MAXN];
int n;

struct Ai{
    int ind;
    ll num;
}ai[MAXN];

bool cmp(Ai x, Ai y)
{
    return x.num > y.num;
}

void calc2n() // 预处理 2 的幂
{
    dn[0] = 1;
    REP(1, n, i)
        dn[i] = ((dn[i - 1] << 1) + MOD) % MOD;
}

ll factor(ll i) //找因数
{
    int cnt = 0;
    for(ll k = 1; k * k <= i; k++){
        if(i % k == 0){
            if(!vis[k]) vis[k] = 1, cnt++;
            if(!vis[i / k]) vis[i / k] = 1, cnt++;
        }
    }
    return cnt;
}

ll cntsum(ll lf, ll ct) // 计算第 2 步中的求和
{
    ll ans = 0;
    for(ll i = 1; i <= ct; i++)
        ans = (ans + dn[lf - i]) % MOD;
    return ans;
}

void work() 
{
    sort(ai + 1, ai + 1 + n, cmp);
    ll lft = n, res = 0; // lft 为尚未标记的数的个数
    for(int i = 1; i <= n; i++){
        ll k = factor(ai[i].ind);
        res = (res + cntsum(lft, k) * ai[i].num % MOD) % MOD;
        lft -= k;
    }
    cout << res;    
}

int main()
{
    cin >> n;
    calc2n();
    REP(1, n, i){
        ai[i].ind = i;
        cin >> ai[i].num;
    }
    work();
    return 0;
}
posted @   anjack_511  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示