标签:
大致题意:
求上升子序列的个数
序列怎么出来的呢,好难懂:
for i = 0 to n-1
print A[i mod m]
A[i mod m] = (X * A[i mod m] + Y * (i + 1)) mod Z
取m=3为例 输入完a[] 以后,a[]不是序列 要按照他的循环 打印 a[0] ,a[1], a[2],a[0],a[1],a[2]....如此,每打印一个做一次A第三行的变换,最后就是0 -> n-1 的序列了。
解题思路:
树状数组+离散化。
动规求法: dp[i]=∑dp[j](j<i&&ans[j]<ans[i])
依据树状数组快速统计可加类区间数据的应用,
可转化成 dp[i]=sum(f[i]-1)+1 ;即以前f[i]-1个数据为底的个数再加上自身。
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 using namespace std; 5 #define N 500005 6 #define mod 1000000007 7 long long c[N],a[N],b[N],f[N],T,n,m,x,y,z,ans,size; 8 void modify(int x,int num){while(x<=n)c[x]+=num,c[x]%=mod,x+=x&-x;} 9 long long sum(int x){int s=0;while(x>0)s+=c[x],s%=mod,x-=x&-x;return s;} 10 void ini(){ 11 memset(c,0,sizeof(c)); 12 ans=0; 13 scanf("%d%d%lld%lld%lld",&n,&m,&x,&y,&z); 14 for(int i=0;i<m;i++) scanf("%lld",&a[i]); 15 for(int i=0;i<n;i++){ 16 f[i]=b[i+1]=a[i%m]; 17 a[i%m]=(x*a[i%m]+y*(i+1))%z; 18 } 19 } 20 int main(){ 21 scanf("%d",&T); 22 for(int K=1;K<=T;K++) 23 { 24 ini(); 25 sort(b+1,b+n+1);//离散化 26 size=unique(b+1,b+n+1)-(b+1); 27 for(int i=0;i<n;i++){ 28 int p=lower_bound(b+1,b+size+1,f[i])-b; 29 long long tot=sum(p-1)+1; 30 ans+=tot; 31 ans%=mod; 32 modify(p,tot); 33 } printf("Case #%d: %lld\n",K,ans); 34 } return 0; 35 }
HDU 3030 - Increasing Speed Limits
标签:
原文地址:http://www.cnblogs.com/nicetomeetu/p/5170327.html