这道题和上篇介绍的hdu 3450 是同一个类型的题。
有点不相同的地方是这道题可以包含长度为1的序列!
方法:树状数组+DP
code:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # include<stdio.h>
2 # include<string.h>
3 # include<stdlib.h>
4 # define N 500005
5 # define mod 1000000007
6 __int64 a[N],b[N],c[N];
7 __int64 count[N];
8 int k;
9 int cmp(const void *a,const void *b)
10 {
11 return *(int *)a - *(int *)b;
12 }
13 int find(__int64 x)
14 {
15 int left,right,mid;
16 left=1;
17 right=k;
18 while(right>=left)
19 {
20 mid=(left+right)/2;
21 if(b[mid]==x) return mid;
22 if(b[mid]>x) right=mid-1;
23 else left=mid+1;
24 }
25 return 0;
26 }
27 __int64 query(int i)
28 {
29 __int64 sum=0;
30 while(i>0)
31 {
32 sum+=count[i];
33 sum%=mod;
34 i-=i&(-i);
35 }
36 return sum;
37 }
38 void insert(int i,__int64 num)
39 {
40 while(i<=k)
41 {
42 count[i]+=num;
43 count[i]%=mod;
44 i+=i&(-i);
45 }
46 }
47 int main()
48 {
49 int i,m,ncase,t,ans,n;
50 __int64 sum,num,X,Y,Z;
51 scanf("%d",&ncase);
52 for(t=1;t<=ncase;t++)
53 {
54 scanf("%d%d%I64d%I64d%I64d",&n,&m,&X,&Y,&Z);
55 for(i=0;i<m;i++)
56 scanf("%d",&a[i]);
57 for(i=0;i<=n-1;i++)
58 {
59 b[i+1]=a[i%m];
60 c[i+1]=b[i+1];
61 a[i%m]=(X*a[i%m]+Y*(i+1))%Z;
62 }
63 qsort(b+1,n,sizeof(b[1]),cmp);
64 k=1;
65 for(i=2;i<=n;i++)
66 if(b[i]!=b[i-1]) b[++k]=b[i];
67 memset(count,0,sizeof(count));
68 sum=0;
69 for(i=1;i<=n;i++)
70 {
71 ans=find(c[i]);
72 num=query(ans-1);
73 num%=mod;
74 sum+=num+1;
75 sum%=mod;
76 insert(ans,num+1);
77 }
78 printf("Case #%d: %I64d\n",t,sum%mod);
79 }
80 return 0;
81 }