T1:无限延展

P3612 [USACO17JAN]Secret Cow Code S

代码实现
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
string s; ll k;
cin >> s >> k;
int n = s.size();
while (n < k) {
ll now = n;
while (now < k) now <<= 1;
now >>= 1;
k -= now+1;
if (k == 0) k = now;
}
cout << s[k-1] << '\n';
return 0;
}

T2:树的最大和

P1122 最大子树和

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
int main() {
int n;
cin >> n;
vector<vector<int>> to(n);
for (int i = 1; i < n; ++i) {
int p;
cin >> p;
--p;
to[p].push_back(i);
}
vector<int> a(n);
rep(i, n) cin >> a[i];
vector<ll> dp(n);
auto dfs = [&](auto& f, int v, int p=-1) -> void {
dp[v] = a[v];
for (int u : to[v]) {
f(f, u, v);
dp[v] += max<ll>(0, dp[u]);
}
};
dfs(dfs, 0);
ll ans = numeric_limits<ll>::max() + 1;
rep(i, n) ans = max(ans, dp[i]);
cout << ans << '\n';
return 0;
}

T3:降低均值

P2115 [USACO14MAR]Sabotage G

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
const double eps = 1e-10;
int main() {
int n;
cin >> n;
vector<int> a(n);
rep(i, n) cin >> a[i];
int tot = accumulate(a.begin(), a.end(), 0);
double wa = 1, ac = 10000;
while (abs(ac-wa) > eps) {
double wj = (ac+wa)/2;
auto ok = [&]{
double t = tot-n*wj;
double now = 0;
for (int i = 1; i < n-1; ++i) {
now += a[i]-wj;
if (now >= t) return true;
if (now < 0) now = 0;
}
return false;
}();
(ok ? ac : wa) = wj;
}
printf("%.2f\n", ac);
return 0;
}

T4:加与乘(二)

可以用一个差分数组来维护操作 1,再用一个差分数组来维护操作 2
然后倒序操作,这样做的目的是避免处理操作 2 里面还有操作 2 这种情况

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
//const int mod = 998244353;
const int mod = 1000000007;
struct mint {
ll x;
mint(ll x=0):x((x%mod+mod)%mod) {}
mint operator-() const {
return mint(-x);
}
mint& operator+=(const mint a) {
if ((x += a.x) >= mod) x -= mod;
return *this;
}
mint& operator-=(const mint a) {
if ((x += mod-a.x) >= mod) x -= mod;
return *this;
}
mint& operator*=(const mint a) {
(x *= a.x) %= mod;
return *this;
}
mint operator+(const mint a) const {
return mint(*this) += a;
}
mint operator-(const mint a) const {
return mint(*this) -= a;
}
mint operator*(const mint a) const {
return mint(*this) *= a;
}
mint pow(ll t) const {
if (!t) return 1;
mint a = pow(t>>1);
a *= a;
if (t&1) a *= *this;
return a;
}
// for prime mod
mint inv() const {
return pow(mod-2);
}
mint& operator/=(const mint a) {
return *this *= a.inv();
}
mint operator/(const mint a) const {
return mint(*this) /= a;
}
};
istream& operator>>(istream& is, mint& a) {
return is >> a.x;
}
ostream& operator<<(ostream& os, const mint& a) {
return os << a.x;
}
struct Q {
char type;
int x, y;
Q() {}
Q(char type, int x, int y): type(type), x(x), y(y) {}
};
int main() {
int n, m;
cin >> n >> m;
vector<Q> qs;
rep(i, m) {
char type;
int x, y;
cin >> type >> x >> y;
--x; --y;
qs.emplace_back(type, x, y);
}
vector<mint> d(n), d2(m);
mint now = 1;
for (int i = m-1; i >= 0; --i) {
now += d2[i];
auto [type, x, y] = qs[i];
if (qs[i].type == '+') {
d[x] += now;
if (y+1 < n) d[y+1] -= now;
}
else {
d2[y] += now;
if (x-1 >= 0) d2[x-1] -= now;
}
}
mint ans;
rep(i, n) {
ans += d[i];
cout << ans << '\n';
}
return 0;
}