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. Java:break和continue关键字的作用

    二者的作用和区别 1. break:直接跳出当前循环体(while.for.do while)或程序块(switch).其中switch case执行时,一定会先进行匹配,匹配成功返回当前case的值 ...

  2. Weka java.lang.reflect.InvocationTargetException

    在用Weka导入数据的时候报 java.lang.reflect.InvocationTargetException 错误,Weka运行包没有给出详细的错误信息,无法查到. 直接调试Weka源码,发现 ...

  3. Selenium自动化测试基础

    如有任何学习问题,可以添加作者微信:lockingfree 目录 Selenium自动化测试基础 Selenium自动化测试第一天(上) Selenium自动化测试第一天(下) Selenium自动化 ...

  4. grep命令及正则

    文本查找 grep,egrep,fgrep grep :Global Research 根据模式搜索文本,并将符合模式的文本行显示出来 模式:Pattern,文本字符和正则的元字符组合而成匹配条件 g ...

  5. leetcode-最大子序和(动态规划讲解)

    最大子序和(动态规划讲解) 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输 ...

  6. 【转】一款已上市MMO手游地图同步方案总结

    转自游戏开发主席 1. 客户端地图格子的相关知识 在2.5D的MMO游戏里,角色是通过3D的方式渲染,2D的地图是通过2D的方式显示,所以在客户端一般会有三个坐标系: a) 3D坐标系:所有需要3D渲 ...

  7. C#二次封装虹软arc研究

    相信很多用C#又想用虹软的SDK的童鞋要花很多心思去研究怎么转换,所以写了一篇文章和一个demo方便用C#的童鞋方便调用虹软的接口, 文章的地址是:https://blog.xgcos.com/sho ...

  8. docker容器学习笔记

    docker是通过内核虚拟化技术来提供容器的资源隔离与安全保障. docker组成: docker client.docker server.docker组件(镜像(image).容器(contain ...

  9. maven项目中没有resource文件夹的问题

    之前使用eclipse创建maven项目,文件夹都是建好的,这几次创建,都没有resource文件夹,需要手动创建resource. 现象描述 在eclipse中,创建maven项目有两种方式: 一种 ...

  10. 四:ResourceManger Restart

    概述: RM是yarn中最重要的组件.但是只有一个RM,因此存在单点失败的问题.RM的重启有两种方式: 1.(Non-work-preserving RM restart) 不保留工作状态的重启   ...