zoukankan      html  css  js  c++  java
  • HDU 4638 Group(莫队)题解

    题意:n个数,每个数有一个值,每次询问一个区间,问你这个区间能分成连续的几段(比如7 1 2 8 就是两端 1 2 和 7 8)

    思路:莫队。因为L、R移动顺序wa了20发...问了一下别人,都是先扩大范围,再缩小...以后就这样写吧...

    代码:

    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include <iostream>
    #include<algorithm>
    using namespace std;
    const int maxn = 100000 + 10;
    int vis[maxn], arr[maxn], ans[maxn];
    int T, n, m, ret;
    struct node{
        int l, r;
        int pos, id;
        bool operator < (const node &x) const{
            if(pos == x.pos) return r < x.r;
            return pos < x.pos;
        }
    }p[maxn];
    void add(int x){
        vis[x] = 1;
        if(vis[x - 1] && vis[x + 1]) ret--;
        else if(!vis[x - 1] && !vis[x + 1]) ret++;
    }
    void del(int x){
        vis[x] = 0;
        if(vis[x - 1] && vis[x + 1]) ret++;
        else if(!vis[x - 1] && !vis[x + 1]) ret--;
    }
    void solve(){
        memset(vis, 0 ,sizeof(vis));
        int L = 1, R = 0;
        ret = 0;
        for(int i = 0; i < m; i++){
            int l = p[i].l, r = p[i].r;
            if(r < L || l > R){
                ret = 0;
                for(int i = L; i <= R; i++)
                    vis[arr[i]] = 0;
                for(int i = l; i <= r; i++)
                    add(arr[i]);
                L = l, R = r;
            }
            while(L > l){
                L--;
                add(arr[L]);
            }
            while(R < r){
                R++;
                add(arr[R]);
            }
            while(L < l){
                del(arr[L]);
                L++;
            }
            while(R > r){
                del(arr[R]);
                R--;
            }
            ans[p[i].id] = ret;
        }
    }
    int main(){
        scanf("%d", &T);
        while(T--){
            scanf("%d%d", &n, &m);
            int block = sqrt(n * 1.0);
            for(int i = 1; i <= n; i++)
                scanf("%d", &arr[i]);
            for(int i = 0; i < m; i++){
                scanf("%d%d", &p[i].l, &p[i].r);
                p[i].id = i;
                p[i].pos = p[i].l / block;
            }
            sort(p, p + m);
            solve();
            for(int i = 0; i < m; i++){
                printf("%d
    ", ans[i]);
            }
        }
        return 0;
    }
  • 相关阅读:
    中断API之enable_irq
    XML和Schema命名空间详解
    “低头”时代,会不会就此终结?
    巨型冰山惊现格陵兰,好莱坞大片场景上演
    半世纪以来最佳英文小说:《英国病人》
    线程锁(互斥锁Mutex)
    Python GIL(Global Interpreter Lock)
    黑暗中的生物:利用奇技淫巧快活生存
    “人工智能”造假:只有人工,没有智能
    克罗地亚:输了世界杯,却赢了全世界
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10582224.html
Copyright © 2011-2022 走看看