zoukankan      html  css  js  c++  java
  • hdu4638 问一段区间能组成多少段连续的数

    题:http://acm.hdu.edu.cn/showproblem.php?pid=4638

    题意:题意为询问一段区间里的数能组成多少段连续的数。

    分析:我们先从左到右地添加数,再假定添加进去的话那么连续段数就加1,由此我们加入一个数x后,要是x-1或x+1在这之前就已经加进去了,那么连续段数就要减一,要是x-1和x+1同时在之前已经加进去了那么就要减二;

       因为题目要求查询一段区间且没有强制在线,所以我们进行离线处理,每当处理完一段区间就记录答案即可;

    #include<bits/stdc++.h>
    using namespace std;
    const int M=1e5+5;
    int n;
    int tr[M],pos[M],a[M],ans[M];
    struct node{
        int l,r,id;
    }q[M];
    bool cmp(node x,node y){
        return x.r<y.r;
    }
    void update(int i,int c){
        while(i<=n)
            tr[i]+=c,i+=i&(-i);
    }
    int query(int i){
        int res=0;
        while(i)
            res+=tr[i],i-=i&(-i);
        return res; 
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            int m;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]),pos[a[i]]=i;
            for(int i=1;i<=m;i++){
                scanf("%d%d",&q[i].l,&q[i].r);
                q[i].id=i;
            }
            sort(q+1,q+1+m,cmp);
            int nowi=1;
            memset(tr,0,sizeof(tr));
            for(int i=1;i<=n;i++){
                update(i,1);
                if(a[i]>1&&pos[a[i]-1]<i)
                    update(pos[a[i]-1],-1);
                if(a[i]<n&&pos[a[i]+1]<i)
                    update(pos[a[i]+1],-1);
                while(nowi<=m&&q[nowi].r==i)
                    ans[q[nowi].id]=query(q[nowi].r)-query(q[nowi].l-1),nowi++;
            }
            for(int i=1;i<=m;i++)
                printf("%d
    ",ans[i]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    SQL 创建存储过程,让主键自增
    C# 实例练习(第二天)
    IT科技企业逻辑思维面试题
    C#学习——简介(第一天)
    C#中 ??、 ?、 ?: 、?.、?[ ]
    SQL Server类型与C#类型对应关系
    ios 键盘折叠
    html 水印效果
    JQuery筛选器全系列介绍
    将时间改为显示:几天前,几小时前,或者几分钟前
  • 原文地址:https://www.cnblogs.com/starve/p/12438872.html
Copyright © 2011-2022 走看看