zoukankan      html  css  js  c++  java
  • BZOJ2217: [Poi2011]Lollipop

    这题挺邪的,主要是观察分析性质吧

    首先对于一段区间,它肯定满足以下条件之一:

    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
    ", (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
    ", ans[x].first, ans[x].second);
        }
        return 0;
    }
  • 相关阅读:
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    MySQL-数据库三范式
    去除IDEA中xml黄色背景
    git查看commit提交记录详情
    spring-定时任务<task:scheduled-tasks>
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9858890.html
Copyright © 2011-2022 走看看