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
  • 相关阅读:
    【转载】警情通报为啥一定是"蓝底白字"?
    我的英语词汇本
    【转载】随便说说字符集和编码
    JavaScript入门笔记
    JavaScript代码规范及其他注意事项
    编程的部分基础知识
    vc++ 6.0相关
    vue 定位
    mpvue 搭建命令
    uni-app 漫长学习之路
  • 原文地址:https://www.cnblogs.com/starve/p/12438872.html
Copyright © 2011-2022 走看看