BZOJ2217: [Poi2011]Lollipop
阿新 • • 發佈:2018-10-27
clu lollipop isdigit ans line 奇偶性 -- zoj getchar
這題挺邪的,主要是觀察分析性質吧
首先對於一段區間,它肯定滿足以下條件之一:
1.左端點有 2
2.右端點有2
3.左右端點都有1
那麽就有,當前區間的答案的奇偶性相同的比當前答案小的答案都在這一段區間裏
這樣找一段最長的和為奇數的區間就可以構造出所有合法的奇數的答案
找出一段最長的和為偶數的區間就可以構造出所有合法偶數的方案
復雜度 O(n)
代碼:
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cctype> #include <cstdio> #include <locale> using namespace std; const int MAXN = 1000005; int n, m, l1, r1, l2, r2, fir, lst; bool has1; int a[MAXN], sum[MAXN]; pair<int,int> ans[MAXN << 1]; inline int getval() { register int c = getchar(); while (!isupper(c)) c = getchar(); return (c == ‘T‘ ? 2 : 1); } inline int rd() { register int x = 0, c = getchar(); while (!isdigit(c)) c = getchar(); while (isdigit(c)) { x = x * 10 + (c ^ 48); c = getchar(); } return x; } int main() { n = rd(); m = rd(); for (int i = 1; i <= n; ++i) { a[i] = getval(); sum[i] = sum[i - 1] + a[i]; has1 |= (a[i] == 1); } for (int i = 1; i <= n; ++i) if (a[i] == 1) { fir = i; break; } for (int i = n; i >= 1; --i) if (a[i] == 1) { lst = i; break; } if (!has1) { register int x = 0; while (m--) { x = rd(); if (x & 1) puts("NIE"); else printf("1 %d\n", (x >> 1)); } return 0; } if (sum[n] & 1) { l1 = 1; r1 = n; while (l1 <= r1) { ans[sum[r1] - sum[l1 - 1]] = make_pair(l1, r1); if (a[l1] == 2) ++l1; else if (a[r1] == 2) --r1; else { ++l1; --r1; } } if ((fir - 1) < (n - lst)) { l2 = fir + 1; r2 = n; } else { l2 = 1; r2 = lst - 1; } while (l2 <= r2) { ans[sum[r2] - sum[l2 - 1]] = make_pair(l2, r2); if (a[l2] == 2) ++l2; else if (a[r2] == 2) --r2; else { ++l2; --r2; } } } else { l2 = 1; r2 = n; while (l2 <= r2) { ans[sum[r2] - sum[l2 - 1]] = make_pair(l2, r2); if (a[l2] == 2) ++l2; else if (a[r2] == 2) --r2; else { ++l2; --r2; } } if ((fir - 1) < (n - lst)) { l1 = fir + 1; r1 = n; } else { l1 = 1; r1 = lst - 1; } while (l1 <= r1) { ans[sum[r1] - sum[l1 - 1]] = make_pair(l1, r1); if (a[l1] == 2) ++l1; else if (a[r1] == 2) --r1; else { ++l1; --r1; } } } register int x = 0; while (m--) { x = rd(); if (!ans[x].first) puts("NIE"); else printf("%d %d\n", ans[x].first, ans[x].second); } return 0; }
BZOJ2217: [Poi2011]Lollipop