题意
求[i,j]的自区间个数,要求子区间的LIS等于父区间的LIS。
思路
poursoul的博客
枚举终点j,每一个并且让符合条件的起点i尽量靠右。那么,在j点时,区间个数为i个。
例如 1 3 2 5 4,LIS的起点是1,j=4时,1 3 2 5 是符合条件的。
我的代码中s数组是标准的lower_bound求LIS的数组。cnt里放的是尽量靠右的起点。
真的很难用语言描述啊,我也是非了很多脑子才懂得。如果听不懂我再说什么,还是点上面的链接去看看poursoul大神的讲解吧。
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <cstdio> #include <vector> #include <cstring> #include <cmath> #include <algorithm> using namespace std ; #define ll long long const int MAXN = 100005 ; ll cnt[MAXN] ; ll s[MAXN] ; int n ; void work(){ ll ans = 0,tmp,top=0; for(int i = 1 ;i<= n ;i++){ scanf("%I64d",&tmp); if(!top || s[top] < tmp){ s[++top]=tmp; if(top == 1)cnt[1] = i; else cnt[top] = cnt[top -1]; ans = cnt[top] ; } else{ ll tmpl = lower_bound(s+1,s+1+top,tmp)-s; if( tmpl == 1)cnt[1]=i; else cnt[tmpl] = cnt[tmpl - 1]; s[tmpl] = tmp; ans += cnt[top]; } } printf("%I64d\n",ans); } int main () { while ( ~scanf ( "%d" , &n )) work(); return 0 ; }
|