牛客 中石大“骏码杯”B. C. I
1. 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- 小菲爱数数
思路:
每个 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 - 最大公约数求和
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;
}

浙公网安备 33010602011771号