• [Solution] P1903 [国家集训队]数颜色 / 维护队列


    支持修改的莫队

    题目地址


    • 对于每一个询问,记录以下内容:

      • ( ext{Left,Right}):左右边界
      • ( ext{Mapping}):时间轴,即在这个询问之前已经完成了前( ext{Mapping})个修改
    • 按照( ext{Left})为第一关键字,( ext{Right})为第二关键字,( ext{Mapping})为第三关键字对询问排序。

    • 莫队状态的转移:

      • 在相同时间里,和普通莫队没有差异。
      • 在不同时间里,如果询问的时间较早需要逐个消除操作的影响。如果询问的时间晚,需要逐个进行操作。
    • 常数优化

      • ( ext{main})函数里的局部变量要快于全局变量。
      • 使用读入/输出优化。
    • Code

      • /*     --- Hope in Hand ---     */
        #include <stdio.h>
        #include <string.h>
        #include <algorithm>
        #define GC getchar()
        #define Clean(X,K) memset(X,K,sizeof(X))
        int Qread () {
            int X = 0 ;
            char C = GC ;
            while (C > '9' || C < '0') C = GC ;
            while (C >='0' && C <='9') {
                X = X * 10 + C - '0' ;
                C = GC ;
            }
            return X ;
        }
        const int Maxn = 50005 , U = 1000005;
        int A[Maxn]  ,Ans[Maxn] , Vis[U];
        struct Node {
            int X , Y , TIME , Mapping , Place , Raw_Value;
        };
        Node Ask [Maxn] , Add[Maxn] ;
        bool Cmp (const Node &A , const Node &B) {
            if (A.X != B.X )return A.X < B.X ;
            if (A.Y != B.Y ) return (A.X &1 ? A.Y < B.Y : A.Y > B.Y ) ;
            return (A.Y & 1 ? A.TIME < B.TIME : A.TIME > B.TIME ) ;
        }
        void Write(int X) {
            if( X > 9 ) Write(X / 10);
            putchar(X % 10+ '0');
        }
        int main () {
            int L = 0 , R = 0 , Time = 0 , Now = 0 , N  ,M , Cq = 0 , Cr = 0 ;
            N = Qread () , M = Qread ();
            for (int i = 1 ; i <= N; ++ i) A[i] = Qread () ;
            for (int i = 1 ; i <= M; ++ i) {
                char C = GC ;
                while (C != 'Q' && C != 'R') C = GC ;
                if (C == 'Q') {
                    Ask[++ Cq].X = Qread () ;
                    Ask[Cq].Y = Qread () ;
                    Ask[Cq].TIME = i ;
                    Ask[Cq].Mapping = Cr ;
                    Ask[Cq].Place = Cq ;
                } else {
                    Add[++Cr].X = Qread () ;
                    Add[Cr].Y = Qread () ;
                    Add[Cr].TIME = i ;
                    Add[Cr].Mapping = Cq ;
                }
            }
            Clean (Vis , 0) ;
            L = R = 1 , Vis[A[L]] = 1 , Now = 1 ;
            std :: sort (Ask + 1 , Ask + 1 + Cq , Cmp) ;
            for (int i = 1 ; i <= Cq ; ++ i) {
                while (L < Ask[i].X ) {
                    -- Vis[A[L]] ;
                    if (!Vis[A[L]]) -- Now ;
                    ++ L ;
                }
          
                while (R < Ask[i].Y ) {
                    ++ R ;
                    ++ Vis[A[R]] ;
                    if (Vis[A[R]] == 1) ++ Now ;
                }
          
                while (R > Ask[i].Y ) {
                    -- Vis[A[R]] ;
                    if (!Vis[A[R]]) -- Now ;
                    -- R ;
                }
                while (Time < Ask[i].Mapping ) {
                    ++ Time ;
                    if (Add[Time].X >= L && Add[Time].X <= R) {
                        --Vis[A[Add[Time].X ]]  ;
                        if (Vis[A[Add[Time].X ]] == 0)  --Now ;
                        ++Vis[Add[Time].Y ]  ;
                        if (Vis[Add[Time].Y ]== 1) ++Now  ;
                    }
                    Add[Time].Raw_Value = A[Add[Time].X ] ;
                    A[Add[Time].X ] = Add[Time].Y ;
                }
                while (Time > Ask[i].Mapping ) {
                    if (Add[Time].X >= L && Add[Time].X <= R) {
                        Vis[Add[Time].Y ] -- ;
                        if (Vis[Add[Time].Y ] == 0) --Now  ;
                        ++Vis[Add[Time].Raw_Value  ]  ;
                        if (Vis[Add[Time].Raw_Value  ]== 1) ++Now  ;
                    }
                    A[Add[Time].X ] = Add[Time].Raw_Value ;
                    --Time ;
                }
                Ans[Ask[i].Place ] = Now ;
            }
          
            for (int i = 1 ; i  <= Cq; ++ i)Write (Ans[i]) , putchar(10);
            fclose (stdin) , fclose (stdout) ;
            return 0 ;
        }
        

    Thanks!

  • 相关阅读:
    手机app数据的爬取之mitmproxy安装教程
    Scrapy库的安装(windows版)
    Cannot uninstall 'html5lib'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
    HTTP 599: SSL certificate problem: unable to get local issuer certificate错误
    requests禁止重定向
    python多线程爬取-今日头条的街拍数据(附源码加思路注释)
    python爬虫-淘宝商品密码(图文教程附源码)
    20131214-HTML基础-第二十一天
    20131214-EditPlus快捷键-第二十一天
    20131209-数据库导入导出数据-sqlhelper-第十七天
  • 原文地址:https://www.cnblogs.com/bj2002/p/10862143.html
Copyright © 2020-2023  润新知