A. 幂运算
构造 那么
满足题意。
void solve(){
int x;cin >> x;
cout << x << " " << 1 << "\n";
}
B. 琪露诺的 K 维偏序
给出的数组已经是有序的了,贪心第 小的数,只需要判断
即可。
当然,这题也可以使用二分查找小于 的数量,然后对比数量。
void solve() {
int n, q;
cin >> n >> q;
vector<int> a(n+9);
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a.begin()+1,a.begin()+n+1);
while (q--) {
int k,x;
cin >> k >> x;
cout << (a[k] < x ? "Yes\n" : "No\n");
}
}
C. 合成大企鹅
结论:每次贪心取最小的两个数合成。
这里给出两种证明办法:(证明方式不唯一)
证明1:取对数考虑,每次操作相当于删了两个数,添加它们的平均数,那么很显然先删的数被平均过最多次,权值是最小的。
证明2:我们倾定两个数 ,那么假设我们对这两个数进行一次合成,那么新得出的数字一定满足
,即每次会对于相较于较大的数来说,结果变小。此时如果操作的
是所有数中最小的两个数,那么产生的数一定是最小的数。所以我们为了保留值尽可能大,就要从最小的数进行操作。
时间复杂度: 到
,瓶颈在排序。
void solve(){
int n;cin >> n;
double ans = 1;
vector<int> a(n+1);
for (int i = 1;i <= n;i ++) cin >> a[i];
sort(a.begin()+1,a.end());
for (int i = 1;i <= n;i ++){
if (i == 1){
ans = a[i];
} else {
ans *= a[i];
ans = sqrt(ans);
}
};
cout << fixed << setprecision(12) << ans << "\n";
}
D/E. ⑨运算
D 题数据范围很小,可以直接跑一次暴力预处理,然后多查。E 题怎么做呢?
首先,考虑不使用操作 2,判断操作 1 是否可以变成全为 9 的数。变的那个数一定是大于等于 的最小的全为 9 的数记为
,如果可以变成的话当且仅当
,答案就为
。
考虑做一次操作 2,我们考虑在操作 2 操作之后等价于原来的操作前的 ,于是我们要操作 2 前尽可能少的步数到达
,然后用一次操作 2。
最后两者答案取最小。
单组测试时间复杂度 。
using i64 = long long;
void solve(){
i64 x;
cin >> x;
i64 y = 9,z;
while(y < x) y = y * 10 + 9;
z = x <= y/9 ? y/9 : y/9*10+1;
i64 ans = 2e18;
if (x%9==0) ans = min(ans,(y-x)/9);
ans = min(ans,(z-x)/9+(z-x)%9+1);
cout << ans << "\n";
}
F. 琪露诺的排列构造
只有 时是无解的。
对于 是奇数,可以构造
,前
项互不相等且为奇数,第
项为偶数不与前面相等。
对于 是偶数,可以构造
。前
项互不相等且是小于
的奇数。而第
和
项大于
,第
项是偶数,所以满足题意。
构造方案不唯一,例如可以特判 后把偶数拆成两个奇数相加(
),独立构造(下方代码)。
单组测试时间复杂度 。
void solve() {
int n;
cin >> n;
if (n <= 2) {
cout << -1 << endl;
}else if (n%2) {
for (int i = 2; i <= n; i++) cout << i << " ";
cout << 1 << endl;
}else if (n == 4) {
cout << "2 4 1 3" << endl;
}else {
cout << "2 3 1 ";
for (int i = 5; i <= n; i++) cout << i << " ";
cout << 4 << endl;
}
}
G. 琪露诺的连续取模求和
记 ,显然有
。
考虑如何计算 :
-
可以证明:
-
-
-
从
到
,有完整的
段
和剩下的一段
。
单组测试时间复杂度 。
using i64 = long long;
i64 cal(i64 n) {
return n*(n+1)/2;
}
void solve() {
i64 l,r,p,q;
cin >> l >> r >> p >> q;
auto f = [&](i64 n) {
return n/q*cal(p-1) + cal(min(n%q,p-1));
};
cout << f(r)-f(l-1) << "\n";
}

京公网安备 11010502036488号