zoukankan      html  css  js  c++  java
  • BZOJ 1878: [SDOI2009]HH的项链

    二次联通门 : BZOJ 1878: [SDOI2009]HH的项链

    /*
        BZOJ 1878: [SDOI2009]HH的项链
        
    
        莫队水过
        
        记录一个count数组
        来记录每个数出现了几次
    
        缩小区间时只要看是否只出现一次
    
        扩张区间时只要看看是否出现过即可
        
    */
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    
    #define Max 1000001
    
    void read (int &now)
    {
        now = 0;
        register char word = getchar ();
        while (word < '0' || word > '9')
            word = getchar ();
        while (word >= '0' && word <= '9')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
    }
    
    int belong[Max];
    
    struct Query_Data
    {
        int l, r;
    
        int Id;
        
        bool operator < (const Query_Data &now) const
        {
            if (belong[now.l] == belong[this->l])
                return this->r < now.r;
            else
                return belong[this->l] < belong[now.l];
        }
    };
    
    
    int N, M;
    
    int number[Max];
    Query_Data query[Max];
    
    int count[Max];
    
    int Result;
    
    bool visit[Max];
    
    inline void Updata (int now, bool type) 
    {
        if (type)
        {
            if (!count[number[now]])
                Result ++;
            count[number[now]] ++;
        }
        else
        {
            if (count[number[now]] == 1)
                Result --;
            count[number[now]] --;
        }
    }
    
    int Answer[Max];
    
    int main (int argc, char *argv[])
    {
        read (N);
        int Size = sqrt (N);
        for (int i = 1; i <= N; i ++)
        {
            read (number[i]);
            belong[i] = (i + 1) / Size;
        }
        read (M);
        for (int i = 1; i <= M; i ++)
        {
            read (query[i].l);
            read (query[i].r);
            query[i].Id = i;
        }
        std :: sort (query + 1, query + 1 + M);
        int l = 1, r = 0;
        for (int i = 1; i <= M; i ++)
        {
            if (l < query[i].l)
                for (int pos = l; pos < query[i].l; pos ++)
                    Updata (pos, false);
            else if (l >= query[i].l)
                for (int pos = l - 1; pos >= query[i].l; pos --)
                    Updata (pos, true);
            if (r > query[i].r)
                for (int pos = r; pos > query[i].r; pos--)
                    Updata (pos, false);
            else if (r <= query[i].r)
                for (int pos = r + 1; pos <= query[i].r; pos++)
                    Updata (pos, true);
            l = query[i].l;
            r = query[i].r;
            Answer[query[i].Id] = Result;
        }
        for (int i = 1; i <= M; i ++)
            printf ("%d
    ", Answer[i]);
        return 0;
    }
  • 相关阅读:
    【Python基础】04_Python中的if判断语句
    【Python基础】03_Python中的命名和关键字
    【Python基础】02_Python中变量的输入输出
    【Python基础】01_Python中的变量
    三、gridView增删改查
    二、MVC3+EF单表增删改查
    一、简单gridview列表展示
    oracle账户密码过期,修改为无限制
    提取年
    如何找到记录的子记录
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/6947007.html
Copyright © 2011-2022 走看看