hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)
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
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.
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
2
1
2
3
6
2
在奔溃的边缘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思想)的更多相关文章
- HDU 3030 - Increasing Speed Limits
Problem Description You were driving along a highway when you got caught by the road police for spee ...
- HDU 6318 - Swaps and Inversions - [离散化+树状数组求逆序数][杭电2018多校赛2]
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=6318 Problem Description Long long ago, there was an ...
- HDU 5792 World is Exploding (离散化+树状数组)
题意:给定 n 个数,让你数出 a < b && c < d && a != b != c != d && Aa < Ab & ...
- HDU 5862 Counting Intersections(离散化 + 树状数组)
Counting Intersections Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- HDU 6447 YJJ’s Salesman (树状数组 + DP + 离散)
题意: 二维平面上N个点,从(0,0)出发到(1e9,1e9),每次只能往右,上,右上三个方向移动, 该N个点只有从它的左下方格点可达,此时可获得收益.求该过程最大收益. 分析:我们很容易就可以想到用 ...
- HDU 5862 Counting Intersections(离散化+树状数组)
HDU 5862 Counting Intersections(离散化+树状数组) 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 D ...
- hdu 3015 Disharmony Trees (离散化+树状数组)
Disharmony Trees Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 6318.Swaps and Inversions-求逆序对-线段树 or 归并排序 or 离散化+树状数组 (2018 Multi-University Training Contest 2 1010)
6318.Swaps and Inversions 这个题就是找逆序对,然后逆序对数*min(x,y)就可以了. 官方题解:注意到逆序对=交换相邻需要交换的次数,那么输出 逆序对个数 即可. 求逆序对 ...
- CodeForces 540E - Infinite Inversions(离散化+树状数组)
花了近5个小时,改的乱七八糟,终于A了. 一个无限数列,1,2,3,4,...,n....,给n个数对<i,j>把数列的i,j两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...
随机推荐
- Hibernate-关系映射
1.为什么用Hibernate框架: java程序数据保存的变化: * 内存存在:java基础中, 数据保存在内存中,只在内存中暂时存在 * 文件保存:有io/流之后,数据可以保存到文件中 * 数据库 ...
- 成都Uber优步司机奖励政策(2月20日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- Java语言简介
Java即计算机编程语言 1.概念 Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征.Jav ...
- dubbo之注册管理中心
一.在dubbo的框架中注册中心是必要的一个环节,这个也是分布式部署的一个必要环节.在dubbo的架构基本图中可以看出,基本上所有的服务都是通过注册中心进行注册,然后在通过注册中心,暴露出接口来. 二 ...
- redis外部访问
1.redis的搭建这里就不做描述的了,可以参考我的另外一个博客. http://www.cnblogs.com/ll409546297/p/6993778.html 2.说明一下我们在其他服务器上面 ...
- 「日常训练&知识学习」树的分块(王室联邦,HYSBZ-1086)
题意与分析 这题的题意就是树分块,更具体的看题目(中文题). 学习这一题是为了树的分块,为树上莫队做铺垫. 参考1:https://blog.csdn.net/LJH_KOQI/article/det ...
- 负数取余/整除,Python和C语言的不同
总结一句:Python中负数整除,是向负无穷取整,所以导致负数取余不对 在数学公式中,两种语言的表示算法都是一样的,都是: r=a-n*[a/n] 以上,r是余数,a是被除数,n是除数. 唯一不同点, ...
- GameplayKit的GKStateMachine用法与实例
GKStateMachine 玩家进入GameScene场景中 -> 通过GKStateMachine进入到指定的游戏状态GKState 在GameScene场景中 -> 根据不同的逻辑调 ...
- Siki_Unity_2-1_API常用方法和类详细讲解(上)
Unity 2-1 API常用方法和类详细讲解(上) 任务1&2:课程前言.学习方法 && 开发环境.查API文档 API: Application Programming I ...
- JDK源码分析:Object.java
一. 序言 Object.java是一切类的基类,所以了解该类有一定的必要 二 .属性及方法分析 方法列表: private static native void registerNatives(); ...