zoukankan      html  css  js  c++  java
  • 【BZOJ 2453】 维护队列

    【题目链接】          

                https://www.lydsy.com/JudgeOnline/problem.php?id=2453

    【算法】                

              带修改的莫队算法  

              当块的大小为N^(2/3)时,时间复杂度为 : O(n^(5/3))

              但本题,当块的大小为sqrt(N)时,能够达到更优的复杂度

    【代码】

                 

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 10010
    const int MAXC = 1e6 + 5;
    
    int i,len,x,y,sum,l,r,n,now,qnum,m,cnt;
    int a[MAXN],block[MAXN],s[MAXC],ans[MAXN];
    char op[5];
    
    template <typename T> inline void read(T &x)
    {
        int f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    template <typename T> inline void write(T x)
    {
        if (x < 0)
        {
            putchar('-');
            x = -x;
        }
        if (x > 9) write(x/10);
        putchar(x%10+'0');
    }
    template <typename T> inline void writeln(T x)
    {
        write(x);
        puts("");
    }
    struct info
    {
        int x,y,last;
    } c[MAXN];
    struct Query
    {
        int x,y,id,cur;
    } q[MAXN];
    
    inline bool cmp(Query a,Query b)
    {
        if (block[a.x] == block[b.x])
        {
            if (block[a.y] == block[b.y]) return a.cur < b.cur;
            else return block[a.y] < block[b.y];
        } else return block[a.x] < block[b.x];        
    }
    inline void add(int x)
    {
        s[a[x]]++;
        if (s[a[x]] == 1) sum++;    
    }
    inline void dec(int x)
    {
        s[a[x]]--;
        if (s[a[x]] == 0) sum--;
    }
    inline void worka(int now)
    {
        int x = c[now].x,y = c[now].y;
        if (x >= l && x <= r) dec(x);
        c[now].last = a[x];
        a[x] = y;
        if (x >= l && x <= r) add(x);    
    }
    inline void workb(int now)
    {
        int x = c[now].x,y = c[now].y;
        if (x >= l && x <= r) dec(x);
        a[x] = c[now].last;
        if (x >= l && x <= r) add(x);
    }
    
    int main()
    {
        
        read(n); read(m);
        len = sqrt(n);
        for (i = 1; i <= n; i++) block[i] = (i - 1) / len + 1;
        for (i = 1; i <= n; i++) read(a[i]);
        for (i = 1; i <= m; i++)
        {
            scanf("%s",&op);
            read(x); read(y);
            if (op[0] == 'Q') q[++qnum] = (Query){x,y,qnum,cnt};
            else c[++cnt] = (info){x,y,0};    
        }
        sort(q+1,q+qnum+1,cmp);
        l = 1; r = 0; now = 0; sum = 0;
        for (i = 1; i <= qnum; i++)
        {
            for (; r < q[i].y; r++) add(r+1);        
            for (; r > q[i].y; r--) dec(r);
            for (; l < q[i].x; l++) dec(l);
            for (; l > q[i].x; l--) add(l-1);
            for (now; now < q[i].cur; now++) worka(now+1);
            for (now; now > q[i].cur; now--) workb(now);
            ans[q[i].id] = sum;
        }
        for (i = 1; i <= qnum; i++) printf("%d
    ",ans[i]);
    
        return 0;
    }
  • 相关阅读:
    有關window.showModalDialog的應用11/30
    phpmyadmin的查詢不出現10/29
    那點事情我沒有精力做10/17
    水晶報表System.InvalidCastException: 指定的轉換無效11/30
    水晶報表匯出時System.InvalidCastException:指定的格式無效10/29
    读博日记(C#常用开源类库收集
    ASP.net通过JQuery实现Ajax操作
    仿Discuz!的论坛评分发帖弹出提示并渐渐消失的效果
    仿Discuz文本框弹出层的效果
    C#开源资源大汇总
  • 原文地址:https://www.cnblogs.com/evenbao/p/9313012.html
Copyright © 2011-2022 走看看