码迷,mamicode.com
首页 > 其他好文 > 详细

hdu5141 线段树

时间:2014-12-11 00:08:07      阅读:289      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   sp   for   

这题说的是给了一串然后计算出这个串的最长递增子序列的长度,然后计算出有过少个子串[i,j] 他们的最长递增子序列和这整个子串的最长递增子序列相同,我们对于每个j最长递增子序列找出他在序列中的使成为最长序列的起始点,如果这个样的点存在多个那么尽量的选取靠右的,这样我们将他们离散后,然后每个线段的叶节点保存这个点的最高排位数是多少和形成他最高排位的最右端点,然后用线段树去维护这个序列, 因为知道优先会让这个点取最高位在选左区间的,这样我们只要枚举每个上升序列长度为LIS的最小区间就好了

bubuko.com,布布扣
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 100005;
typedef long long ll;
int cL, cR, cH, cloc, op;
struct Itree{
  int H[maxn*4],loc[maxn*4];
  void build(int o, int L, int R){
       memset(H,0,sizeof(H));
              memset(loc,0,sizeof(loc));
  }
  void query(int o, int L, int R){
         if(cL<=L&&R<=cR){
           if(op==0){
                  op=1;
                  cH=H[o];
                  cloc=loc[o];
            }else {
            if( H[o] > cH || ( H[o] == cH &&loc[o]>cloc)){
              cH=H[o]; cloc=loc[o];
            }
           }
           return ;
        }
       int mid=(L+R)>>1;
       if(cL<=mid) query(o*2,L,mid);
       if(cR>mid) query(o*2+1,mid+1,R);
}
void maintain(int o){
  if(H[o*2]>H[o*2+1]||(H[o*2] == H[o*2+1] && loc[o*2] > loc[o*2+1] ) ){
          H[o]=H[o*2]; loc[o]=loc[o*2];
  }else{
     H[o]=H[o*2+1] ; loc[o]=loc[o*2+1];
  }
}
void update(int o , int L, int R){
  if(L==R){
     // if(cH>H[o]||(cH==H[o]&&cloc>loc[o])){
         H[o]=cH;loc[o]=cloc;
      //}
     return ;
  }
  int mid = (L+R)>>1;
  if(op <= mid) update( o * 2 , L , mid );
  else  update( o * 2 + 1 , mid + 1 , R );
  maintain(o);
  }
}T;
int H[maxn];
int Loc[maxn];
struct seg{
  int L, R,d;

}P[maxn];
int main()
{
      int n;
      while(scanf("%d",&n)==1){
         for(int i=0; i<n; ++i) {
             scanf("%d",&H[i]);
             Loc[i]=H[i];
         }
        sort(Loc,Loc+n);
      int num=unique(Loc,Loc+n)-Loc;
      for( int i = 0 ; i < n; ++ i )
       H[i] = lower_bound(Loc,Loc+num,H[i])-Loc+1;
      int ge=1;
    T.build(1,0,num);
    int g=0;
    for(int i=0; i<n; ++i){
        op=0;
        cL=0; cR=H[i]-1;
        T.query(1,0,num);
        cH++;
        if( cH == 1 ){
            cloc = i;
        }
            P[g].L=cloc; P[g].R=i;P[g].d=cH; g++;
       ge=max(ge,cH);
       op=H[i];
       T.update(1,0,num);
    }
       ll ans=0,L=n;
      for(int i=g-1; i>=0; --i)
        if(P[i].d==ge){
            ans += (P[i].L+1)*(L-P[i].R);
            L=P[i].R;
      }
      printf("%I64d\n",ans);
 }
 return 0;
}
View Code

 

hdu5141 线段树

标签:style   blog   http   io   ar   color   os   sp   for   

原文地址:http://www.cnblogs.com/Opaser/p/4156619.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!