zoukankan      html  css  js  c++  java
  • HDU 5289——Assignment——————【RMQ+优化求解】

    Assignment

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 902    Accepted Submission(s): 441


    Problem Description
    Tom owns a company and he is the boss. There are n staffs which are numbered from 1 to n in this company, and every staff has a ability. Now, Tom is going to assign a special task to some staffs who were in the same group. In a group, the difference of the ability of any two staff is less than k, and their numbers are continuous. Tom want to know the number of groups like this.
     
    Input
    In the first line a number T indicates the number of test cases. Then for each case the first line contain 2 numbers n, k (1<=n<=100000, 0<k<=10^9),indicate the company has n persons, k means the maximum difference between abilities of staff in a group is less than k. The second line contains n integers:a[1],a[2],…,a[n](0<=a[i]<=10^9),indicate the i-th staff’s ability.
     
    Output
    For each test,output the number of groups.
     
    Sample Input
    2 4 2 3 1 2 4 10 5 0 3 4 5 2 1 6 7 8 9
     
    Sample Output
    5 28
    Hint
    First Sample, the satisfied groups include:[1,1]、[2,2]、[3,3]、[4,4] 、[2,3]
     
    题目大意:给你t组测试数据。每组有n,k。表示有序列长度为n,求有多少个连续的区间满足区间内的任意元素之差小于k。
    解题思路:现在用i,j分别表示左右区间位置。然后从左往右扩展,如果要扩展的那个元素跟区间内的任意元素差值都小于k,则res++,且区间向右扩展一个长度。直到遇到元素Aj,跟区间内的某个元素发生冲突,那么我停止向右扩展这个Aj。然后我让原来的区间[i,j-1]左区间向右移动一个位置。我向右移动左区间,那么这个区间内的符合的区间个数必然比刚才的[i,j-1]这个区间少一个,那么res--。然后这时候继续扩展上次发生冲突的位置j,看现在的区间是否能跟Aj不发生冲突。然后一直重复地操作。简单总结就是如果右区间能扩展,就扩展;不能扩展,让左区间向右移动一个位置,然后看现在的区间能不能让右区间向右扩展。
     
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define INT long long
    const int maxn=1e5+20;
    int d[maxn][50];
    int dp[maxn][50];
    int A[maxn];
    int Abs(int x){
        return x<0? -x:x;
    }
    void RMQ_init(int n){//RMQ维护出区间i,j之间的最大最小值。
        for(int i=0;i<n;i++){
            d[i][0]=A[i];
            dp[i][0]=A[i];
        }
        for(int j=1;(1<<j)<=n;j++){
            for(int i=0;i+(1<<j)-1<n;i++){
                d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]);
                dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
            }
        }
    }
    int RMQ(int L,int R,int typ){
        int k=0;
        while((1<<(k+1)<=R-L+1))
              k++;
        if(typ==0)
            return min(d[L][k],d[R-(1<<k)+1][k]);
        else
            return max(dp[L][k],dp[R-(1<<k)+1][k]);
    }
    int main(){
        int t,i,j,k,n,tmp,ret,itvlav,itvliv,sum,flag;
        INT res,ans;
        scanf("%d",&t);
        while(t--){
            memset(dp,0,sizeof(dp));
            memset(d,0,sizeof(d));
            memset(A,0,sizeof(A));
            scanf("%d%d",&n,&k);
            for(i=0;i<n;i++){
                scanf("%d",&A[i]);
            }
            RMQ_init(n);
            tmp=0,res=0,sum=0;
            itvlav=itvliv=A[0];
            for(i=0;i<n;i++){
                flag=0;
                for(j=tmp;j<n;j++){
                    if(Abs(itvlav-A[j])<k&&Abs(itvliv-A[j])<k){//右区间能向右扩展
                        tmp=j+1;
                        itvlav=RMQ(i,j,1);
                        itvliv=RMQ(i,j,0);
                        res++;
                    }else{  //右区间现在无法扩展,向右移动左区间位置,看新的区间是否能向右扩展
                        flag=1;
                        tmp=j;
                        itvlav=RMQ(i+1,j-1,1);
                        itvliv=RMQ(i+1,j-1,0);
                        break;
                    }
                }
                sum+=res;
                res--;
                if(flag==1){
                     if(res==0){
                        itvlav=itvliv=A[tmp];
                     }
                }
    
    
            }
            printf("%lld
    ",sum);
        }
        return 0;
    }
    

      

  • 相关阅读:
    poj1286 polya计数法
    hdu 2079 普通母函数的应用
    hdu1521 指数型母函数 求解多重集排列数
    hdu1398 普通母函数的应用 解决多重集组合问题
    hdu1085 多重部分和问题
    二部图最大匹配问题的求解 匈牙利算法
    tarjan算法
    Prim算法
    无向图连通图(割)
    无向图找桥
  • 原文地址:https://www.cnblogs.com/chengsheng/p/4667394.html
Copyright © 2011-2022 走看看