专栏文章
题解:AT_abc150_e [ABC150E] Change a Little Bit
AT_abc150_e题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mio03i0d
- 此快照首次捕获于
- 2025/12/02 11:10 3 个月前
- 此快照最后确认于
- 2025/12/02 11:10 3 个月前
一个显然的拆贡献,因为 的组合达到了 ,考虑每一个 的贡献。
首先,对于一对特定的 ,有一个显然的贪心:肯定首先选择 较小的那一位修改。
由于改变 中元素的顺序不影响答案,将 从小到大排序,对于当前位 ,若 ,不需要改变,不产生贡献,于是只考虑 的情况。
对于第 至 位,肯定优先于第 位改变,对当前的 没有影响。
对于第 至 位,肯定优先选第 位改变,此时 即为 第 至第 位不同位数的个数再加上第 位这一对。
此时在第 至第 位有 组不同的方案数即为 ,因为第 至 位状态随意,则第 至第 位有 组不同,且第 至第 位有任意组不同的总方案数即为 ,则该位的总贡献为:
最后的答案即为:
此时 预处理组合数, 计算答案,可以得到 。
然后考虑优化。
令 ,答案即为:
考虑如何快速求 。
(不清楚原因的可以去背一背关于组合数的公式)
答案即为:
但是你会发现输出 比答案 小,可以计算发现 ,很容易找到这个规律。
但是为什么呢?
我们会发现漏考虑了一个东西:我们枚举的是 和 不同的方案数。当 和 时, 和 都算做不同,这是两种方案,而我们只算作了一种。同理, 和 相同的也有两种情况。由于 和 有 位,所以答案需要乘上 。
代码
CPP#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 200050, MOD = 1e9 + 7;
int qpow(int a, int b){
int t = 1;
for(; b; b >>= 1){
if(b & 1) t = (ll)t * a % MOD;
a = (ll)a * a % MOD;
}
return t;
}
int n, ans = 0, u = 0;
int a[N];
int main() {
cin >> n;
for(int i = 1; i <= n; i ++)
cin >> a[i];
sort(a + 1, a + n + 1);
for(int i = 1; i <= n; i ++){
if(i < n) u = ((ll)(n - i) * qpow(2, n - i - 1) % MOD + qpow(2, n - i)) % MOD;
else u = 1;
ans = (ans + (ll)a[i] * qpow(2, i - 1) % MOD * u % MOD) % MOD;
}
cout << (ll)ans * qpow(2, n) % MOD;
return 0;
}
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...