zoukankan      html  css  js  c++  java
  • hdu-4638-Group(树状数组)

    题意

    找到区间里有多少组连续数字串

    分析:

    (转)思路:显然,我们要使得value最大,就要尽量将连续的ID分在一组,所以问题转化为求一个区间中连续ID区间的个数。我们从左往右扫描,依次考虑右端点为i的询问,设dp[l]为区间[l,i]的连续区间个数,po[i]为i出现的位置,若还未出现,则为0,设我们当前考虑的右端点为a[i],首先我们假设a[i]不能和区间[1,i-1]中的任何一个数分到一组,则我们要将dp[1]到dp[i-1]全部加1,然后考虑po[a[i]+1]是否不为0,若不为0则说明a[i]-1已经在前面出现,则我们需要将dp[1]到dp[po[a[i]+1]]全部减一个1,因为a[i]可以和a[i]+1分为一组,则我们之前加的1是多余的。对于a[i]-1的情况同理。以上操作可以由线段树或者树状数组什么的实现,然后再将询问按照右端点从小到大排序,离线处理即可,以下是代码实现

    // File Name: 1007.cpp
    // Author: Zlbing
    // Created Time: 2013年08月02日 星期五 07时44分46秒
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    const int MAXN=1e5+100;
    int tree[MAXN];
    int n;
    int lowbit(int x)
     {
         return x&(-x);
     }
     
     void add(int pos,int val)////如果要把a[i]增加v,可以通过调用如下函数实现
     {
         while(pos <=n)
         {
             tree[pos] += val;
             pos += lowbit(pos);//pos+lowbit(x)可以理解变成了x的父亲
         }
     }
     
     int read(int x)//前x项和
     {
         int s=0;
         while(x>0)
         {
             s += tree[x];
             x -= lowbit(x);//x-lowbit(x)可以理解成变成了x的兄弟
         }
         return s;
     }
    int A[MAXN],pos[MAXN];
    struct node{
        int l,r,index;
        bool operator <(const node& rsh)const{
            if(r==rsh.r)
                return l<rsh.l;
            else return r<rsh.r;
        }
    };
    vector<node> Q;
    int ans[MAXN];
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int m;
            scanf("%d%d",&n,&m);
            REP(i,1,n){
                scanf("%d",&A[i]);
                pos[A[i]]=i;
            }
            Q.clear();
            node tmp;
            REP(i,1,m)
            {
                scanf("%d%d",&tmp.l,&tmp.r);
                tmp.index=i;
                Q.push_back(tmp);
            }
            sort(Q.begin(),Q.end());
            CL(tree,0);
            int j=0;
            for(int i=1;i<=n;i++)
            {
                add(i,1);
                if(A[i]+1<=n&&pos[A[i]+1]<i)
                {
                    add(pos[A[i]+1],-1);
                }
                if(A[i]-1>=1&&pos[A[i]-1]<i)
                {
                    add(pos[A[i]-1],-1);
                }
                while(Q[j].r==i)
                {
                    ans[Q[j].index]=read(Q[j].r)-read(Q[j].l-1);
                    j++;
                }
            }
            REP(i,1,m)
            {
                printf("%d
    ",ans[i]);
            }
        }
        return 0;
    }
  • 相关阅读:
    java短信验证和注册
    java两个对象属性比较
    mysql像通讯录一样把中文按字母排序的sql
    开发APP必须知道的API集合,来源http://www.cnblogs.com/wikiki/p/7232388.html
    第三方短信接口使用测试
    Guava google缓存机制
    Integer 使用==判断127和超过128的数据的区别
    js加密后台加密解密以及验证码
    sqlserver system object type
    为RadComboBox添加SelectionChanging事件
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3232977.html
Copyright © 2011-2022 走看看