LightOJ 1085(树状数组+离散化+DP,线段树)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LightOJ 1085(树状数组+离散化+DP,线段树)相关的知识,希望对你有一定的参考价值。
Description
An increasing subsequence from a sequence A1, A2 ... An is defined by Ai1, Ai2 ... Aik, where the following properties hold
- i1 < i2 < i3 < ... < ik and
- 2. Ai1 < Ai2 < Ai3 < ... < Aik
Now you are given a sequence, you have to find the number of all possible increasing subsequences.
Input
Input starts with an integer T (≤ 10), denoting the number of test cases.
Each case contains an integer n (1 ≤ n ≤ 105) denoting the number of elements in the initial sequence. The next line will contain n integers separated by spaces, denoting the elements of the sequence. Each of these integers will be fit into a 32 bit signed integer.
Output
For each case of input, print the case number and the number of possible increasing subsequences modulo 1000000007.
Sample Input
3
3
1 1 2
5
1 2 1000 1000 1001
3
1 10 11
Sample Output
Case 1: 5
Case 2: 23
Case 3: 7
题解:让求单调递增序列的个数;dp[i]=sum(dp[j])+1(j<i);由于数太大,需要离散化由于是单调的,所以当相等的时候树状数组要从大到小inset,以免对后面相等的造成影响,还可以用线段树写;
树状数组:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> using namespace std; #define mem(x,y) memset(x,y,sizeof(x)) #define SI(x) scanf("%d",&x) #define PI(x) printf("%d",x) #define P_ printf(" ") const int MOD=1000000007; typedef long long LL; const int INF=0x3f3f3f3f; const int MAXN=1e5+100; int dp[MAXN],a[MAXN],p[MAXN]; int N; int lowbit(int x){return x&(-x);} void insert(int x,int v){ while(x<=N){ dp[x]=(dp[x]+v)%MOD; x+=lowbit(x); } } int sum(int x){ int ans=0; while(x>0){ ans=(ans+dp[x])%MOD; x-=lowbit(x); } return ans; } int cmp(int x,int y){ if(a[x]!=a[y])return a[x]<a[y]; else return x>y; } int main(){ int T,kase=0; SI(T); while(T--){ SI(N); for(int i=1;i<=N;i++)SI(a[i]),p[i]=i; sort(p+1,p+N+1,cmp); mem(dp,0); for(int i=1;i<=N;i++){ insert(p[i],sum(p[i])+1); } printf("Case %d: %d\n",++kase,sum(N)); } return 0; }
线段树:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> using namespace std; #define mem(x,y) memset(x,y,sizeof(x)) #define SI(x) scanf("%d",&x) #define PI(x) printf("%d",x) #define P_ printf(" ") const int MOD=1000000007; typedef long long LL; const int INF=0x3f3f3f3f; const int MAXN=1e5+100; #define lson root<<1,l,mid #define rson root<<1|1,mid+1,r #define ll root<<1 #define rr root<<1|1 int tree[MAXN<<2],p[MAXN],a[MAXN]; int ans=0; void pushup(int root){ tree[root]=(tree[ll]+tree[rr])%MOD; } void insert(int root,int l,int r,int flog,int v){ int mid=(l+r)>>1; if(l==flog&&r==flog){ tree[root]=v; return; } if(mid>=flog)insert(lson,flog,v); if(mid<flog)insert(rson,flog,v); pushup(root); } void sum(int root,int l,int r,int L,int R){ int mid=(l+r)>>1; if(l>=L&&r<=R){ ans=(ans+tree[root])%MOD; return; } if(mid>=L)sum(lson,L,R); if(mid<R)sum(rson,L,R); return; } int cmp(int x,int y){ if(a[x]!=a[y])return a[x]<a[y]; else return x>y; } int main(){ int T,N,kase=0; SI(T); while(T--){ SI(N); for(int i=1;i<=N;i++)SI(a[i]),p[i]=i; sort(p+1,p+N+1,cmp); mem(tree,0); for(int i=1;i<=N;i++){ ans=0; sum(1,1,N,1,p[i]); insert(1,1,N,p[i],ans+1); } printf("Case %d: %d\n",++kase,tree[1]); } return 0; }
以上是关于LightOJ 1085(树状数组+离散化+DP,线段树)的主要内容,如果未能解决你的问题,请参考以下文章
LightOJ 1085 - All Possible Increasing Subsequences 树状数组+离散
HDU 5542 - The Battle of Chibi - [离散化+树状数组优化DP]
Increasing Speed Limits HDU - 3030 dp 树状数组 离散化 上升子序列