首页 > 代码库 > HDU5141--LIS again (LIS变形)
HDU5141--LIS again (LIS变形)
题意一个序列的LIS为MAX, 求连续子序列的LIS为MAX的个数。
先求出LIS,记录以a[i]结尾的LIS的长度,以及LIS起始位置(靠右的起始位置)。
然后线性扫一遍,,线段树与树状数组的差距还是蛮大的,,线段树900+MS,险些超时,而树状数组仅仅400+MS
代码里注释部分为线段树做法。
1 #include <set> 2 #include <map> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 typedef unsigned long long ull; 16 typedef long long ll; 17 const int inf = 0x3f3f3f3f; 18 const double eps = 1e-8; 19 const int maxn = 1e5+10; 20 int seg[maxn<<2],pt[maxn<<2],a[maxn],vec[maxn],idx,n; 21 int pos1[maxn],pos2[maxn]; 22 void hash_() 23 { 24 sort(vec,vec+idx); 25 idx = unique(vec,vec+idx) - vec; 26 for (int i = 0; i < n ;i++) 27 a[i] = lower_bound(vec,vec+idx,a[i]) - vec + 1; 28 } 29 int ans,pp; 30 /* 31 void update(int l,int r,int pos,int x,int val,int s) 32 { 33 if (l == r) 34 { 35 if (val == seg[pos] && s > pt[pos]) 36 pt[pos] = s; 37 if (val > seg[pos]) 38 { 39 pt[pos] = s; 40 seg[pos] = val; 41 } 42 return ; 43 } 44 int mid = (l + r) >> 1; 45 if (x <= mid) 46 update(l,mid,pos<<1,x,val,s); 47 else 48 update(mid+1,r,pos<<1|1,x,val,s); 49 seg[pos] = max(seg[pos<<1],seg[pos<<1|1]); 50 if (seg[pos<<1] > seg[pos<<1|1]) 51 pt[pos] =pt[pos<<1]; 52 if (seg[pos<<1] < seg[pos<<1|1]) 53 pt[pos] = pt[pos<<1|1]; 54 if (seg[pos<<1] == seg[pos<<1|1]) 55 pt[pos] = max(pt[pos<<1],pt[pos<<1|1]); 56 } 57 void query(int l,int r,int pos,int ua,int ub) 58 { 59 if (ub < ua) 60 return ; 61 if (ua <= l && ub >= r) 62 { 63 if (ans < seg[pos]) 64 { 65 ans = seg[pos]; 66 pp = pt[pos]; 67 } 68 if (ans == seg[pos] && pp < pt[pos]) 69 pp = pt[pos]; 70 return ; 71 } 72 int mid = (l + r) >> 1; 73 if (ua <= mid) 74 query(l,mid,pos<<1,ua,ub); 75 if (ub > mid) 76 query(mid+1,r,pos<<1|1,ua,ub); 77 }*/ 78 inline int lowbit (int x) 79 { 80 return x & -x; 81 } 82 int c[2][maxn]; 83 void add(int x,int d,int s) 84 { 85 while (x <= idx) 86 { 87 if (c[0][x] < d) 88 { 89 c[0][x] = d; 90 c[1][x] = s; 91 } 92 if (c[0][x] == d && c[1][x] < s) 93 { 94 c[1][x] = s; 95 } 96 x += lowbit(x); 97 } 98 } 99 void query(int x)100 {101 while (x)102 {103 if (ans < c[0][x])104 {105 pp = c[1][x];106 ans = c[0][x];107 }108 if (ans == c[0][x] && pp < c[1][x])109 {110 pp = c[1][x];111 }112 x -= lowbit(x);113 }114 }115 int dp[maxn];116 int main(void)117 {118 #ifndef ONLINE_JUDGE119 freopen("in.txt","r",stdin);120 #endif121 while (~scanf ("%d",&n))122 {123 //memset(seg,0,sizeof(seg));124 //memset(pt,0,sizeof(pt));125 memset(c,0,sizeof(c));126 idx = 0;127 for (int i = 0; i < n; i++)128 {129 scanf("%d",a+i);130 vec[idx++] = a[i];131 }132 hash_();133 int LIS = 0;134 for (int i = 0; i < n; i++)135 {136 ans = 0;137 //query(1,n,1,1,a[i]-1);138 query(a[i]-1);139 dp[i] = ans + 1;140 if (ans == 0)141 pos1[i] = i;142 else143 pos1[i] = pp;144 // update(1,n,1,a[i],dp[i],pos1[i]);145 add(a[i],dp[i],pos1[i]);146 LIS = max(dp[i],LIS);147 }148 int pre = n;149 for (int i = n -1; i >= 0; i--)150 {151 if (dp[i] != LIS)152 continue;153 pos2[i] = pre-1;154 pre = i;155 }156 ll cnt = 0;157 for (int i = 0; i < n; i++)158 {159 if (dp[i] != LIS)160 continue;161 cnt += (ll)(pos1[i] + 1) * (pos2[i]+1-i);162 }163 printf("%I64d\n",cnt);164 }165 return 0;166 }
HDU5141--LIS again (LIS变形)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。