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;
    }
  • 相关阅读:
    .net core 3.1 添加区域 area
    JMeter 网站并发测试工具使用教程
    .net core 3.1 使用ado.net
    .net core 3.1 mvc 调试的时 更改cshtml页面 刷新浏览器不更新
    .net core 3.1 autofac(webapi / mvc 通过)
    .net core3.1 rest api 无法接收 vue 中 axios 请求
    .net core 3.1 web api 允许跨域
    mysql 中文匹配
    mysql 分组排序
    mysql json处理
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10582224.html
Copyright © 2011-2022 走看看