HDU 3030 Increasing Speed Limits

http://acm.hdu.edu.cn/showproblem.php?pid=3030

本来想的是DP的算法,但是DP的话明显要超时的。

然后文哥告诉我的用树状数组的方法,我一直想怎么用树状数组来表示。。

看文哥模拟,然后知道。。。

想将数组离散化,然后记录第i个位置为结尾的序列的个数(就是DP的思想了)。。

并且每次都要更新以 第 i 个元素为结尾的序列的当前的个数,这里用到了树状数组更新。

View Code
  1 #include <iostream>
  2 #include <algorithm>
  3 using namespace std;
  4 const int maxn = 500005;
  5 const int mod = 1000000007;
  6 long long  ans[maxn],has[maxn],temp[maxn],x,y,z,n,m;
  7 
  8 int lowbit(int i)
  9 {
 10     return i & (-i);
 11 }
 12 
 13 long long getSum(int i)
 14 {
 15     long long sum=0;
 16     while(i)
 17     {
 18         sum+=temp[i];
 19         sum%=mod;
 20         i-=lowbit(i);
 21     }
 22     return sum;
 23 }
 24 
 25 void modfiy(int i,int c)
 26 {
 27     while(i<maxn)
 28     {
 29         temp[i]+=c;
 30         i+=lowbit(i);
 31     }
 32 }
 33 
 34 void make()
 35 {
 36     int i,j;
 37     j=1;
 38     if(m>=n)
 39     {
 40         for(i=0;i<n;i++)
 41             ans[j++]=has[i];
 42         
 43     }
 44     else
 45     {
 46         for(i=0;i<n;i++)
 47         {
 48             ans[j++]=has[i%m];
 49             has[i%m]=(x*has[i%m]+y*(i+1))%z;
 50         }
 51     }
 52     for(i=1;i<=n;i++)
 53         temp[i]=ans[i];
 54     sort(temp+1,temp+n+1);
 55     has[1]=temp[1];
 56     for(i=2,j=2;i<=n;i++)
 57         if(temp[i]!=temp[i-1])
 58             has[j++]=temp[i];
 59     m=j;
 60 }
 61 
 62 int search(long long num)
 63 {
 64     int i,j,mid;
 65     i=1;    j=m-1;
 66     while(i<=j)
 67     {
 68         mid=(i+j)/2;
 69         if(num==has[mid])
 70             return mid;
 71         if(num>has[mid])
 72             i=mid+1;
 73         else
 74             j=mid-1;
 75             
 76     }
 77     return mid;
 78 }
 79 
 80 
 81 int main()
 82 {
 83     int t,i,j,l,ch;
 84     cin>>t;
 85     for(l=1;l<=t;l++)
 86     {
 87         cin>>n>>m>>x>>y>>z;
 88         for(i=0;i<m;i++)
 89             cin>>has[i];
 90         make();
 91         for(i=0;i<maxn;i++)
 92             temp[i]=0;
 93         for(i=1;i<=n;i++)
 94         {
 95             ch=search(ans[i]);
 96             ans[i]=getSum(ch-1)+1;
 97             modfiy(ch,ans[i]);
 98         }
 99         long long sum=0;
100         cout<<"Case #"<<l<<": ";
101         for(i=1;i<=n;i++)
102             sum=(sum+ans[i])%mod;
103         cout<<sum<<endl;
104     }
105     return 0;
106 }
posted @ 2012-10-01 11:19  YORU  阅读(386)  评论(0编辑  收藏  举报