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;
}