Increasing Speed Limits

Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 481    Accepted Submission(s): 245

Problem Description
You were driving along a highway when you got caught by the road police for speeding. It turns out that they\'ve been following you, and they were amazed by the fact that you were accelerating the whole time without using the brakes! And now you desperately need an excuse to explain that.

You've decided that it would be reasonable to say "all the speed limit signs I saw were in increasing order, that\'s why I've been accelerating". The police officer laughs in reply, and tells you all the signs that are placed along the segment of highway you drove, and says that's unlikely that you were so lucky just to see some part of these signs that were in increasing order.

Now you need to estimate that likelihood, or, in other words, find out how many different subsequences of the given sequence are strictly increasing. The empty subsequence does not count since that would imply you didn't look at any speed limits signs at all!

For example, (1, 2, 5) is an increasing subsequence of (1, 4, 2, 3, 5, 5), and we count it twice because there are two ways to select (1, 2, 5) from the list.

 
Input
The first line of input gives the number of cases, N. N test cases follow. The first line of each case contains n, m, X, Y and Z each separated by a space. n will be the length of the sequence of speed limits. m will be the length of the generating array A. The next m lines will contain the m elements of A, one integer per line (from A[0] to A[m-1]).

Using A, X, Y and Z, the following pseudocode will print the speed limit sequence in order. mod indicates the remainder operation.

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

Note: The way that the input is generated has nothing to do with the intended solution and exists solely to keep the size of the input files low.

1 ≤ m ≤ n ≤ 500 000

 
Output
For each test case you should output one line containing "Case #T: S" (quotes for clarity) where T is the number of the test case and S is the number of non-empty increasing subsequences mod 1 000 000 007.
 
Sample Input
2
5 5 0 0 5
1
2
1
2
3
6
2 2 1000000000 6
1
2
 
Sample Output
Case #1: 15
Case #2: 13
 
Source
 
Recommend
gaojie   |   We have carefully selected several similar problems for you:  3450 2227 2642 1255 3743 
 

在奔溃的边缘a了,搞了近一天= =!!

题意开始也没弄懂,后来知道是由一个数组推出目标数组(s[]):

for(int i=0;i<m;i++)
    scanf("%d",&a[i]);
for(int i=0;i<n;i++){
    s[i]=a[i%m];
    t[i]=s[i]; //用于离散化处理
    a[i%m]=(x*a[i%m]+y*(i+1))%z;
}

然后离散化处理:

sort(t,t+n);
cnt=0;
a[++cnt]=t[0];
for(int i=1;i<n;i++){
    if(t[i]!=t[i-1]){
        a[++cnt]=t[i];
    }
}

此处是简单的处理,实际运用则是在二分查找里(search());

最后处理目标数组s[],由dp思想可以从前状态推出后状态!然后用树状数组实现,时间复杂度就是O(n*lgn),贡献了了好多次TLE,一开始用map,后来才换成二分,map耗时较大,明白了简单的不一定好,出来混迟早要还的!!

 //2218MS    8136K    1668 B    G++
#include<iostream>
#include<map>
#include<algorithm>
#define M 1000000007
#define N 500005
#define ll __int64
using namespace std;
int c[N],a[N],t[N],s[N];
int cnt;
inline int lowbit(int k)
{
return (-k)&k;
}
inline void update(int k,int detal)
{
for(int i=k;i<=cnt;i+=lowbit(i)){
c[i]+=detal;
if(c[i]>=M) c[i]%=M;
}
}
inline int getsum(int k)
{
int s=;
for(int i=k;i>;i-=lowbit(i)){
s+=c[i];
if(s>=M) s%=M;
}
return s;
}
inline int search(int a0[],int m)
{
int l=,r=cnt,mid;
while(l<r){
mid=(l+r)>>;
if(a0[mid]<m) l=mid+;
else r=mid;
}
return l;
}
int main(void)
{
int cas,n,m,k=;
ll x,y,z;
scanf("%d",&cas);
while(cas--)
{
memset(c,,sizeof(c));
scanf("%d%d%I64d%I64d%I64d",&n,&m,&x,&y,&z);
for(int i=;i<m;i++)
scanf("%d",&a[i]);
for(int i=;i<n;i++){
s[i]=a[i%m];
t[i]=s[i];
a[i%m]=(x*a[i%m]+y*(i+))%z;
}
sort(t,t+n);
cnt=;
//map<int,int>Map;
//Map[t[0]]=++cnt;
a[++cnt]=t[];
for(int i=;i<n;i++){
if(t[i]!=t[i-]){
//Map[t[i]]=++cnt;
a[++cnt]=t[i];
}
}
ll ans=;
update(,);
for(int i=;i<n;i++){
int id=search(a,s[i]); //离散化的二分查找
int temp=getsum(id);
ans+=temp; //dp思想
if(ans>=M) ans%=M;
update(id+,temp);
}
printf("Case #%d: %I64d\n",k++,ans);
}
return ;
}

hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)的更多相关文章

  1. HDU 3030 - Increasing Speed Limits

    Problem Description You were driving along a highway when you got caught by the road police for spee ...

  2. HDU 6318 - Swaps and Inversions - [离散化+树状数组求逆序数][杭电2018多校赛2]

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=6318 Problem Description Long long ago, there was an ...

  3. HDU 5792 World is Exploding (离散化+树状数组)

    题意:给定 n 个数,让你数出 a < b && c < d && a != b != c != d  && Aa < Ab & ...

  4. HDU 5862 Counting Intersections(离散化 + 树状数组)

    Counting Intersections Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  5. HDU 6447 YJJ’s Salesman (树状数组 + DP + 离散)

    题意: 二维平面上N个点,从(0,0)出发到(1e9,1e9),每次只能往右,上,右上三个方向移动, 该N个点只有从它的左下方格点可达,此时可获得收益.求该过程最大收益. 分析:我们很容易就可以想到用 ...

  6. HDU 5862 Counting Intersections(离散化+树状数组)

    HDU 5862 Counting Intersections(离散化+树状数组) 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 D ...

  7. hdu 3015 Disharmony Trees (离散化+树状数组)

    Disharmony Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  8. HDU 6318.Swaps and Inversions-求逆序对-线段树 or 归并排序 or 离散化+树状数组 (2018 Multi-University Training Contest 2 1010)

    6318.Swaps and Inversions 这个题就是找逆序对,然后逆序对数*min(x,y)就可以了. 官方题解:注意到逆序对=交换相邻需要交换的次数,那么输出 逆序对个数 即可. 求逆序对 ...

  9. CodeForces 540E - Infinite Inversions(离散化+树状数组)

    花了近5个小时,改的乱七八糟,终于A了. 一个无限数列,1,2,3,4,...,n....,给n个数对<i,j>把数列的i,j两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...

随机推荐

  1. 北京Uber优步司机奖励政策(1月17日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  2. 13 内建属性 _getattribute_ 内建函数

    1.内建属性 2.__getattribute__ 属性访问时拦截器 class Itcast(object): def __init__(self,subject1): self.subject1 ...

  3. gdb 分析出错

    1 创建测试代码test.php <?php function test1(){ while(true){ sleep(1); } }echo getmypid() "\r\n&quo ...

  4. python删除文本中的所有空字符

    import re import os input_path = 'G:/test/aa.json' output_path ='G:/test/bb.json' with open(input_pa ...

  5. 「国庆训练&知识学习」图的最大独立集与拓展(Land of Farms,HDU-5556)

    题意 一个\(N*M\)的矩阵,其中"."代表空地,"0-9"代表古代建筑,我们如果选择了一个编号的古代建筑想要建立,那么对应就要将全部该编号的建筑建立起来,如 ...

  6. hdu1231最大连续子序列(动态规划)

    最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  7. jmeter常用测试元件

    1.线程组 线程组是任何测试计划的起点,所有的逻辑控制器和采样器都必须放在线程组下.其他的测试元件(例如监听器)可以直接放在测试计划下,这些测试元件对所有的线程组都生效. 每一个JMeter线程都会完 ...

  8. 查看linux系统版本命令汇总

    Linux下如何查看版本信息, 包括位数.版本信息以及CPU内核信息.CPU具体型号等等,整个CPU信息一目了然.   1.Linux查看版本当前操作系统内核信息   命令:uname -a

  9. Linux命令大全(非常全,史上最全)

    最近学习Linux,最大的体验就是它的很多东西都需要由命令来进行控制,下面是我总结的一些命令,供大家参考: 系统信息   arch 显示机器的处理器架构 uname -m 显示机器的处理器架构 una ...

  10. TPO-10 C2 Return a literature book

    TPO-10 C2 Return a literature book 第 1 段 1.Listen to a conversation between a student and an employe ...