BZOJ2217: [Poi2011]Lollipop

1.左端点有 2

2.右端点有2

3.左右端点都有1

代码：

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

posted @ 2018-10-26 21:46  AWordThatWeDefine  阅读(134)  评论(0编辑  收藏  举报