好老的题了,但是还是很有做头的。
stl
SPFA
Dijkstra
我们发现这道题每个操作只对其后面又影响,然后我们想到DP要求的无后效性,于是我们直接倒着DP一下就好了。 (最重要的是这道题有取东西的顺序)
DP
#include <cstdio> #include <iostream> using namespace std; #define forn(i) for(int i=1;i<=n;++i) const int maxn = 1e5 + 10; int opt[maxn], a[maxn]; int main() { freopen("explo.in","r",stdin); freopen("explo.out","w",stdout); double n, k, c, w; cin >> n >> k >> c >> w; forn(i) cin >> opt[i] >> a[i]; double p_1 = 1-0.01*k; double p_2 = 1+0.01*c; double ans = 0; for (int i = n; i; -- i) if (opt[i] & 1) ans = max(ans, ans * p_1 + a[i]); else ans = max(ans, ans * p_2 - a[i]); printf("%.2lf", ans*w); return 0; }
emmm,这道题暴力都可以70分。我怕不吸氧set过不了,于是写了个70的部分分,然后写了个stl版正解 70pts: 首先根据抽屉原理,如果询问长度 \(\ge q\) 那就必有前缀和模\(q\)相等,或者这个数本身被\(q\)整除,然后因为\(q \le 200\)直接\(n ^ 2\)暴力
set
100pts: 考虑已经定下来一端,我们只需要寻找另外一段,是的他们的差值最小就行了,于是自然的写出二分。维护的话,考虑平衡树,或者set都可以。
set版
#include <cstdio> #include <iostream> #include <set> using namespace std; typedef long long qword; #define pb push_back #define forn(i) for(int i=1;i<=n;++i) #define rep(i,s,t) for(int i=(int)(s);i<=(int)(t);++i) int n, m; const int maxn = 5e5 + 10; int a[maxn]; qword sum[maxn]; inline void Init() { cin >> n >> m; forn(i) cin >> a[i]; forn(i) sum[i] = sum[i - 1] + a[i]; } qword mod(qword x, int p) { x %= p; while (x < 0) x += p; return x % p; } inline void work() { int L, R, Q; qword ans; while (m--) { cin >> L >> R >> Q; ans = Q; if (R - L >= Q) {cout << 0 << endl; continue;} rep(i,L,R) rep(j,i,R) ans = min(ans, mod(sum[j] - sum[i - 1],Q)); cout << ans << endl; } } inline void solve() { int L, R, Q; qword ans; while (m--) { cin >> L >> R >> Q; ans = Q; if (R - L + 1 >= Q) {cout << 0 << endl; continue;} set<qword> s; s.insert(0); rep(i,L,R) { qword w = mod(sum[i] - sum[L - 1], Q); set<qword>::iterator it = s.upper_bound(w); if (it != s.begin()) --it; ans = min(ans, mod(w - *it, Q)); s.insert(w); } cout << ans << endl; } } #define OK int main() { #ifdef OK freopen("seq.in","r",stdin); freopen("seq.out","w",stdout); ios::sync_with_stdio(0); #endif // OK Init(); if(n <= 100000 && m<=10000) work(); else solve(); }