A题:
简单的计算题,开long double防止精度问题;
#include<bits/stdc++.h>
using i64 = long long;
int main(){
std::ios::sync_with_stdio(0);
std::cin.tie(0);
int n; std::cin >> n;
long double pie = 3.14159265358979;
long double ans = ((double)n / 2.0) * ((double)n / 2.0) * pie;
printf("%.13Lf", ans);
return 0;
}B题:
简单计数题,根据查询直接计算就可以;
#include<bits/stdc++.h>
using i64 = long long;
int main(){
std::ios::sync_with_stdio(0);
std::cin.tie(0);
int h, w; std::cin >> h >> w;
int q; std::cin >> q;
while(q--){
int chose, x; std::cin >> chose >> x;
if(chose == 1){
std::cout << x * w << '\n';
h -= x;
}else{
std::cout << x * h << '\n';
w -= x;
}
}
return 0;
}C题:
简单题,用一个滑动窗口统计对应字母数量即可;
#include<bits/stdc++.h>
using i64 = long long;
int main(){
std::ios::sync_with_stdio(0);
std::cin.tie(0);
int n, l, r; std::cin >> n >> l >> r;
std::string s; std::cin >> s;
std::map<char, int> cnt;
for(int i = l;i <= r;i++) cnt[s[i]]++;
i64 ans = 0;
for(int i = 0;i < n;i++){
if(i != 0){
if(i + l >= n) break;
cnt[s[i + l - 1]]--;
if(i + r < n) cnt[s[i + r]]++;
}
ans += cnt[s[i]];
}
std::cout << ans;
return 0;
}D题:
这题太阴了,这题是数据量在1e6有简单做法(O(n)),但是一开始走了O(1)做法卡了半天;
由题目,可以看出来这道题的规律, x在偶数时形成的图像全局来看就是一个正方形,且边长为 |x|×2+1;根据这个就可以遍历一轴来计算黑点;代码ai跑的,如下:
#include <iostream>
#include <algorithm>
using namespace std;
// 计算 [l, r] 区间内有多少个偶数喵
long long count_even(long long l, long long r) {
if (l > r) return 0;
auto f = [](long long x) {
if (x >= 0) return x / 2;
return (x - 1) / 2;
};
return f(r) - f(l - 1);
}
int main() {
// 优化输入输出速度喵
ios_base::sync_with_stdio(false);
cin.tie(NULL);
long long L, R, D, U;
if (!(cin >> L >> R >> D >> U)) return 0;
long long total_black = 0;
for (long long x = L; x <= R; ++x) {
long long X = x >= 0 ? x : -x;
// 计算与 [-X, X] 的区间交集喵
long long inter_l = max(D, -X);
long long inter_r = min(U, X);
// 第一部分:在 [-X, X] 内部的 y
if (inter_l <= inter_r) {
if (X % 2 == 0) {
total_black += (inter_r - inter_l + 1);
}
}
// 第二部分:在 [-X, X] 下方的 y
if (D < -X) {
long long bottom_r = min(U, -X - 1);
total_black += count_even(D, bottom_r);
}
// 第三部分:在 [-X, X] 上方的 y
if (U > X) {
long long top_l = max(D, X + 1);
total_black += count_even(top_l, U);
}
}
cout << total_black << "\n";
return 0;
}实际上可以吧坐标都转化到第一象限来计算,所以只考虑一象限用容斥定理来做这道题就行;对于坐标 x1,\ x2,\ y1,\ y2,记 f(x, y)为点 (0, 0) 到点 (x,y)的黑点个数,化坐标后就可以这样计算:
sum = f(x2, y2) - f(x2, y1 - 1) - f(x1 - 1, y2) + f(x1 - 1, y1 - 1)
所以重点放在坐标变化和 f的计算上,发现实际上任意的一象限坐标对应的 f(x, y)都是一个正方形加上一个矩形,那么计算也就解决了,如下:
正方形为{(0, 0)} × {(m, m)};矩形为{(m, m)} × {(x, y)}或{(y, x)}
std::function<i64(i64, i64)> getSum = [&](i64 x, i64 y) ->i64 {
if(x < 0 || y < 0) return 0;
i64 m = std::min(x, y);
i64 k = (m / 2) + 1;
i64 ans = k * (2 * k - 1);//等差数列求和
if(x > y){
ans += (y + 1) * ((x / 2) - m / 2);计算矩形内的黑点数
}else if(y > x){
ans += (x + 1) * ((y / 2) - m / 2);
}
return ans;
};坐标的变化,就是把其他象限的部分折到第一象限,只考虑边界就会简单很多,如下:
std::function<std::vector<std::pair<i64, i64>>(i64, i64)> getq = [&](i64 px, i64 ix) ->std::vector<std::pair<i64, i64>> {
std::vector<std::pair<i64, i64>> now;
if(px >= 0) now.push_back({px, ix});
else if(ix < 0) now.push_back({-ix, -px});
else{
now.push_back({1, -px});
now.push_back({0, ix});
}
return now;
};最后O(1)计算答案即可,代码如下:
#include<bits/stdc++.h>
using i64 = long long;
int main(){
std::ios::sync_with_stdio(0);
std::cin.tie(0);
i64 x1, x2, y1, y2; std::cin >> x1 >> x2 >> y1 >> y2;
std::function<std::vector<std::pair<i64, i64>>(i64, i64)> getq = [&](i64 px, i64 ix) ->std::vector<std::pair<i64, i64>> {
std::vector<std::pair<i64, i64>> now;
if(px >= 0) now.push_back({px, ix});
else if(ix < 0) now.push_back({-ix, -px});
else{
now.push_back({1, -px});
now.push_back({0, ix});
}
return now;
};
std::function<i64(i64, i64)> getSum = [&](i64 x, i64 y) ->i64 {
if(x < 0 || y < 0) return 0;
i64 m = std::min(x, y);
i64 k = (m / 2) + 1;
i64 ans = k * (2 * k - 1);
if(x > y){
ans += (y + 1) * ((x / 2) - m / 2);
}else if(y > x){
ans += (x + 1) * ((y / 2) - m / 2);
}
return ans;
};
std::function<i64(i64, i64, i64, i64)> query = [&](i64 px, i64 ix, i64 py, i64 iy){
i64 sum = getSum(ix, iy) - getSum(px - 1, iy) - getSum(ix, py - 1) + getSum(px - 1, py - 1);
return sum;
};
auto gx = getq(x1, x2);
auto gy = getq(y1, y2);
i64 ans = 0;
for(const auto& i : gx){
for(const auto& j : gy){
ans += query(i.first, i.second, j.first, j.second);
}
}
std::cout << ans;
return 0;
}
评论