NOIP模擬(10.20)T1 刮刮卡
阿新 • • 發佈:2019-02-14
刮刮卡
c和sum,也相當於和前面一模一樣的複製了一遍,那麼只要找到所有sum裡面最小的一個,從他後面開始取,就一定可以取完了······
題目背景:
10.20 NOIP模擬T1
分析:字首和 or 單調佇列
我們來看這道有意思的題目,定義陣列c,c[i] = b[i] - a[i],那麼對於以i位置開始的決策,也就是對於一段連續的c[i] + c[i + 1] + c[i + 2] + … + c[j]小於0時,交易停止,那麼我們對於c求一個前綴合sum陣列,sum[i] = sum[1]+ sum[2] + … + sum[i],那麼現在對於i來說,就是找到第一個小於sum[i - 1]的sum,這個可以選擇將陣列倍長一發然後直接單調佇列······但是,我們注意到題目還有一個性質,a陣列之和是等於b陣列之和的,那麼其實我們倍長之後的陣列求
單調佇列:
Source:
/* created by scarlyw */ #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <algorithm> #include <cctype> #include <set> #include <map> #include <vector> #include <queue> #include <ctime> inline char read() { static const int IN_LEN = 1024 * 1024; static char buf[IN_LEN], *s, *t; if (s == t) { t = (s = buf) + fread(buf, 1, IN_LEN, stdin); if (s == t) return -1; } return *s++; } ///* template<class T> inline void R(T &x) { static bool iosig; static char c; for (iosig = false, c = read(); !isdigit(c); c = read()) { if (c == -1) return ; if (c == '-') iosig = true; } for (x = 0; isdigit(c); c = read()) x = ((x << 2) + x << 1) + (c ^ '0'); if (iosig) x = -x; } //*/ const int OUT_LEN = 1024 * 1024; char obuf[OUT_LEN], *oh = obuf; inline void write_char(char c) { if (oh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), oh = obuf; *oh++ = c; } template<class T> inline void W(T x) { static int buf[30], cnt; if (x == 0) write_char('0'); else { if (x < 0) write_char('-'), x = -x; for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48; while (cnt) write_char(buf[cnt--]); } } inline void flush() { fwrite(obuf, 1, oh - obuf, stdout); } /* template<class T> inline void R(T &x) { static bool iosig; static char c; for (iosig = false, c = getchar(); !isdigit(c); c = getchar()) { if (c == -1) return ; if (c == '-') iosig = true; } for (x = 0; isdigit(c); c = getchar()) x = ((x << 2) + x << 1) + (c ^ '0'); if (iosig) x = -x; } //*/ const int MAXN = 2000000 + 10; const int INF = ~0u >> 1; int n; int a[MAXN], b[MAXN], sum[MAXN], pos[MAXN]; inline void read_in() { R(n); for (int i = 1; i <= n; ++i) R(b[i]), b[i + n] = b[i]; for (int i = 1; i <= n; ++i) R(a[i]), a[i + n] = a[i]; for (int i = 1; i <= 2 * n; ++i) sum[i] = sum[i - 1] + b[i] - a[i]; } inline void solve() { static int q[MAXN], head, tail; head = 1, q[tail = 1] = 0, sum[2 * n + 1] = -INF; for (int i = 1; i <= 2 * n + 1; ++i) { while (head <= tail && q[head] < i - n) pos[q[head]] = q[head] + n, head++; while (head <= tail && sum[q[tail]] > sum[i]) pos[q[tail]] = i, tail--; q[++tail] = i; } for (int i = 1; i <= 2 * n; ++i) sum[i] = sum[i - 1] + b[i]; int ans = 0; for (int i = 0; i < n; ++i) if (sum[pos[i]] - sum[i] > sum[pos[ans]] - sum[ans]) ans = i; std::cout << ans; } int main() { // freopen("rock.in", "r", stdin); // freopen("rock.out", "w", stdout); read_in(); solve(); return 0; }
求sum最小(膜拜xehoth dalao):
Source:
#include <bits/stdc++.h> namespace IO { inline char read() { static const int IN_LEN = 1000000; static char buf[IN_LEN], *s, *t; s == t ? t = (s = buf) + fread(buf, 1, IN_LEN, stdin) : 0; return s == t ? -1 : *s++; } template <typename T> inline bool read(T &x) { static char c; static bool iosig; for (c = read(), iosig = false; !isdigit(c); c = read()) { if (c == -1) return false; c == '-' ? iosig = true : 0; } for (x = 0; isdigit(c); c = read()) x = x * 10 + (c ^ '0'); iosig ? x = -x : 0; return true; } inline void read(char &c) { while (c = read(), isspace(c) && c != -1) ; } inline int read(char *buf) { register int s = 0; register char c; while (c = read(), isspace(c) && c != -1) ; if (c == -1) { *buf = 0; return -1; } do buf[s++] = c; while (c = read(), !isspace(c) && c != -1); buf[s] = 0; return s; } const int OUT_LEN = 1000000; char obuf[OUT_LEN], *oh = obuf; inline void print(char c) { oh == obuf + OUT_LEN ? (fwrite(obuf, 1, OUT_LEN, stdout), oh = obuf) : 0; *oh++ = c; } template <typename T> inline void print(T x) { static int buf[30], cnt; if (x == 0) { print('0'); } else { x < 0 ? (print('-'), x = -x) : 0; for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 | 48; while (cnt) print((char)buf[cnt--]); } } inline void print(const char *s) { for (; *s; s++) print(*s); } inline void flush() { fwrite(obuf, 1, oh - obuf, stdout); } struct InputOutputStream { template <typename T> inline InputOutputStream &operator>>(T &x) { read(x); return *this; } template <typename T> inline InputOutputStream &operator<<(const T &x) { print(x); return *this; } ~InputOutputStream() { flush(); } } io; } namespace { using IO::io; const int MAXN = 1000000; #define long long long int a[MAXN * 2 + 2], b[MAXN * 2 + 2]; int r[MAXN * 2 + 2]; long sum[MAXN * 2 + 1]; inline void solve() { register int n; io >> n; for (register int i = 1; i <= n; i++) io >> b[i]; for (register int i = 1, x; i <= n; i++) io >> x, sum[i] = b[i] - x; for (register int i = 1; i <= n; i++) sum[i] += sum[i - 1]; register int min = INT_MAX, pos = -1; for (register int i = 0; i < n; i++) { if (sum[i] < min) { min = sum[i], pos = i; } } io << pos; } } int main() { // freopen("rock.in", "r", stdin); // freopen("rock.out", "w", stdout); solve(); return 0; }