[TJOI2014] Ascending subsequence

 

    When I just did it, I looked at it: Isn't this a stupid question hhhhh. . . . Then I found that I couldn't pass the example after writing, so I took a closer look at the question: isomorphism is one type.

    How can this be done?

    In fact, it is very simple. Let f[i] be the number of ascending subsequences ending with a[i]. We consider that if i is currently counted, then we need to query for a[j] < a[i] and j < i The sum of all f[j].

    In order to avoid double calculation, we only need to keep the one with the largest j for each weight, because that j can definitely contain all the previous answers.

    

    So we can maintain it while calculating.

 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=100005,ha=1000000007;
inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}
int a[maxn],num[maxn],ky,n,f[maxn],ans,g[maxn],pre[maxn];
inline void update(int x,int y){ for(;x<=ky;x+=x&-x) f[x]=add(f[x],y);}
inline int query(int x){ int an=0; for(;x;x-=x&-x) an=add(an,f[x]); return an;}
int main(){
//	freopen("data.in","r",stdin);
//	freopen("data.out","w",stdout);
	
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",a+i),num[i]=a[i];
	sort(num+1,num+n+1);
	ky=unique(num+1,num+n+1)-num-1;
	for(int i=1;i<=n;i++) a[i]=lower_bound(num+1,num+ky+1,a[i])-num;
	
	for(int i=1;i<=n;i++){
		if(pre[a[i]]) update(a[i],ha-pre[a[i]]);
		g[i]=add(query(a[i]-1),1),update(a[i],g[i]);
		pre[a[i]]=g[i];
	}
	
	for(int i=1;i<=ky;i++) if(pre[i]) ans=add(ans,pre[i]-1);
	
	printf("%d\n",ans);
	return 0;
}

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324973607&siteId=291194637