牛客 中石大“骏码杯”B. C. I

1. B - 上分

B - 上分

思路:

全排列

key code:

void dfs(int x1, int ti, int re)  //x1为已经计算过的题数, ti为此时已经花费的时间,re为此时的分数
{
	if(x1 > n || ti > m)   //超过题数或时间,直接返回
	    return ;
	
	res = max(res, re);
	for(int i = 0; i < n; i ++)
	{
		if(!st[i])
		{
			int r = max(a[i] * 0.3, a[i] - (ti + b[i]) * (a[i] * 0.004) - c[i] * 50);
			st[i] = true;
			dfs(x1 + 1, ti + b[i], re + r);
			st[i] = false;
		}
	}
}

void solve()
{
	//try it again
	cin >> n >> m;
	for(int i = 0; i < n; i ++)
		cin >> a[i] >> b[i] >> c[i];
		
	dfs(0, 0, 0);
	cout << res << endl;
	res = 0;
	return ;
}

 

2. C- 小菲爱数数

C - 小菲爱数数

思路:

每个 a [i] 的质因子,对答案的贡献为x * (x + 1) / 2, x为一段含有相同质因子n的数的个数。用 map 存下每个质因子在该数组中所有出现的位置,采用正难则反,计算出每个质因子连续不出现的一段对答案的影响 m,用 总数 - m 即可得出答案。

key code:

LL fun(int n)
{
    return n * (n + 1) / 2;
}
void solve()
{
    //try it again
    int n;
    cin >> n;
    map<int, vector<int>> mp;
    for(int i = 1; i <= n; i ++)
    {
        int x;
        cin >> x;
        for(int j = 2; j <= x / j; j ++)
        {
            if(x % j == 0)
            {
                mp[j].push_back(i);   //存取每个质因子在数组中所有出现的位置
                while(x % j == 0)
                    x /= j;
            }
        }
        if(x > 1) mp[x].push_back(i);
    }
    LL res = 0;
    for(auto [p, v] : mp)
    {
        res += fun(n);       //记录初始的总数
        v.push_back(n + 1);  //保证计算到第n个数对答案的影响
        int last = 0;         //初始化为0,保证计算到第1个数对答案的影响
        for(auto x : v)
        {
            res -= fun(x - last - 1);   //减去连续不出现的一段对答案的影响
            last = x;                   //记录上一次该质因子出现的位置
        }
    }
    cout << res << endl;
}

 

3. I - 最大公约数求和

I - 最大公约数求和

3月25日:快速幂和线性筛的板子题,但是该题时间复杂度卡的很严格,大致理解了别人代码的优化方法,但是g[x]的求解还不是太懂,有没有大佬可以帮忙解释一下的。

3月26日:哈哈,昨天补题的时候看代码没看懂,以为是没想明白,今天看题解,原来这个题难度评分这么高,哈哈,好像不太是我能补的题,以及从未见过的知识点——积性函数,那就以后学这个知识点了再来补这个题吧。

key code:

LL qmi(LL a, LL k)
{
	LL res = 1;
	while(k)
	{
		if(k & 1) res = (LL)res * a % mod;
		k >>= 1;
		a = (LL) a * a % mod;
	}
	return res;
}
void solve()
{
	//try it again
	cin >> n >> k;
	LL sum = 1;
	g[1] = 1;
	
	for(LL i = 2; i <= n; i ++)
	{
		if(!st[i])
		{
			p[++ cnt] = i;
			pw[i] = qmi(i, k);
			g[i] = k % i == 0 ? i : 1;
		}
		for(int j = 1; i * p[j] <= n; j ++)
		{
			int x  = i * p[j];
			st[x] = true;
			g[x] = g[i] * (k / g[i] % p[j] == 0 ? p[j] : 1);
			pw[x] = 1LL * pw[i] * pw[p[j]] % mod;
			if(i % p[j] == 0) break;
		}
		sum = (sum + 1LL * g[i] * pw[i]) % mod;
	}
	cout << sum << endl;
}

 

posted @ 2023-03-26 04:21  breeze_ku  阅读(58)  评论(0)    收藏  举报