zoukankan      html  css  js  c++  java
  • 【bzoj3809】Gty的二逼妹子序列

    *题目描述:
    Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题。
    对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数。
    为了方便,我们规定妹子们的美丽度全都在[1,n]中。
    给定一个长度为n(1<=n<=100000)的正整数序列s(1<=si<=n),对于m(1<=m<=1000000)次询问“l,r,a,b”,每次输出sl…sr中,权值∈[a,b]的权值的种类数。
    *输入:
    第一行包括两个整数n,m(1<=n<=100000,1<=m<=1000000),表示数列s中的元素数和询问数。
    第二行包括n个整数s1…sn(1<=si<=n)。
    接下来m行,每行包括4个整数l,r,a,b(1<=l<=r<=n,1<=a<=b<=n),意义见题目描述。
    保证涉及的所有数在C++的int内。
    保证输入合法。
    *输出:
    对每个询问,单独输出一行,表示sl…sr中权值∈[a,b]的权值的种类数。
    样例输入:
    10 10
    4 4 5 1 4 1 5 1 2 1
    5 9 1 2
    3 4 7 9
    4 4 2 5
    2 3 4 7
    5 10 4 4
    3 9 1 1
    1 4 5 9
    8 9 3 3
    2 2 1 6
    8 9 1 4
    *样例输出:
    2
    0
    0
    2
    1
    1
    1
    0
    1
    2
    *提示:
    样例的部分解释:
    5 9 1 2
    子序列为4 1 5 1 2
    在[1,2]里的权值有1,1,2,有2种,因此答案为2。
    3 4 7 9
    子序列为5 1
    在[7,9]里的权值有5,有1种,因此答案为1。
    4 4 2 5
    子序列为1
    没有权值在[2,5]中的,因此答案为0。
    2 3 4 7
    子序列为4 5
    权值在[4,7]中的有4,5,因此答案为2。
    建议使用输入/输出优化。
    *题解:
    莫队+分块。将询问离线莫队分块以后,再按a和b的权值分块来统计区间的个数。时间复杂度为O(n*sqrt(n))。
    *代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    
    #ifdef WIN32
        #define LL "%I64d"
    #else
        #define LL "%lld"
    #endif
    
    #ifdef CT
        #define debug(...) printf(__VA_ARGS__)
        #define setfile() 
    #else
        #define debug(...)
        #define filename ""
        #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
    #endif
    
    #define R register
    #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
    #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
    #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
    #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
    #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
    char B[1 << 15], *S = B, *T = B;
    inline int FastIn()
    {
        R char ch; R int cnt = 0; R bool minus = 0;
        while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
        ch == '-' ? minus = 1 : cnt = ch - '0';
        while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
        return minus ? -cnt : cnt;
    }
    #define maxn 100010
    #define maxm 1000010
    int a[maxn], block, n, id[maxn], cnt[maxn], bcnt[maxn], ans[maxm];
    struct Query
    {
        int l, r, a, b, id;
    }q[maxm];
    inline bool operator < (const Query &i, const Query &j)
    {
        return id[i.l] != id[j.l] ? i.l < j.l : (id[i.l] & 1 ? i.r > j.r : i.r < j.r);
    }
    inline int query(R int aa, R int bb)
    {
        R int tmp = 0;
        if (id[aa] == id[bb])
        {
            for (R int i = aa; i <= bb; ++i)
                if (cnt[i]) ++tmp;
        }
        else
        {
            for (R int i = aa; i < (id[aa] + 1) * block; ++i)
                if (cnt[i]) ++tmp;
            for (R int i = id[bb] * block; i <= bb; ++i)
                if (cnt[i]) ++tmp;
            for (R int i = id[aa] + 1; i < id[bb]; ++i)
                tmp += bcnt[i];
        }
        return tmp;
    }
    inline void add(R int x)
    {
        ++cnt[x];
        if (cnt[x] == 1) ++bcnt[id[x]];
    }
    inline void del(R int x)
    {
        --cnt[x];
        if (!cnt[x]) --bcnt[id[x]];
    }
    int main()
    {
    //  setfile();
        n = FastIn(); R int m = FastIn(); block = sqrt(n);
        for (R int i = 1; i <= n; ++i) a[i] = FastIn(), id[i] = i / block;
        for (R int i = 1; i <= m; ++i)
        {
            q[i] = (Query) {FastIn(), FastIn(), FastIn(), FastIn(), i};
        }
        std::sort(q + 1, q + m + 1);
        R int l = 1, r = 0;
        for (R int i = 1; i <= m; ++i)
        {
            while (l < q[i].l) del(a[l]), ++l;
            while (r > q[i].r) del(a[r]), --r;
            while (l > q[i].l) --l, add(a[l]);
            while (r < q[i].r) ++r, add(a[r]);
            ans[q[i].id] = query(q[i].a, q[i].b);
        }
        for (R int i = 1; i <= m; ++i) printf("%d
    ", ans[i] );
        return 0;
    }
  • 相关阅读:
    Codevs 2296 仪仗队 2008年省队选拔赛山东
    Codevs 1535 封锁阳光大学
    Codevs 1069 关押罪犯 2010年NOIP全国联赛提高组
    Codevs 1218 疫情控制 2012年NOIP全国联赛提高组
    Codevs 1684 垃圾陷阱
    洛谷 P1108 低价购买
    Vijos P1325桐桐的糖果计划
    Codevs 3289 花匠 2013年NOIP全国联赛提高组
    Codevs 2611 观光旅游(floyed最小环)
    C语言基础之彩色版C语言(内含linux)
  • 原文地址:https://www.cnblogs.com/cocottt/p/5550949.html
Copyright © 2011-2022 走看看