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两个元素做交换.求交换后数列的逆序对数. 很容易想到离散化+树 ...
随机推荐
- 北京Uber优步司机奖励政策(1月19日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 成都Uber优步司机奖励政策(1月30日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 为啥学蛇和python10年后的变化
作者:cheng rianley链接:https://www.zhihu.com/question/22112542/answer/166053516来源:知乎著作权归作者所有.商业转载请联系作者获得 ...
- android学习七 菜单
1.菜单分类 常规菜单 子菜单 上下文菜单 图标菜单 辅助菜单 交替菜单 2.菜单类 andriod.view.menu 3.菜单的参数 名称:字符串标题 菜单ID:整数 ...
- Putty远程连接Ubuntu14.04
步骤一.在ubuntu系统中安装ssh,可使用如下的命令进行安装: sudo apt-get install openssh-server 步骤二.为了保险起见,安装完成后重启一下ssh服务,命令如下 ...
- 浅析Win8/8.1下安装SQL Server 2005 出现服务项无法正常启动解决方案
如何才能在微软最新的Windows8/Windows 8.1下正常使用SQL Server 2005套件呢?下面就简单介绍利用文件替换法,解决其服务项无法正常启动的临时方案.当然还是建议使用SQL S ...
- Katalon 学习笔记(一)
工具介绍: Katalon Studio是一个能提供一整套功能来实现Web,API和Mobile的全自动测试解决方案的自动化测试平台.Katalon Studio构建于开源Selenium和App ...
- HDU - 6441(费马大定理)
链接:HDU - 6441 题意:已知 n,a,求 b,c 使 a^n + b^n = c^n 成立. 题解:费马大定理 1.a^n + b^n = c^n,当 n > 2 时无解: 2. 当 ...
- [Clr via C#读书笔记]Cp11事件
Cp11事件 类型之所以提供事件通知功能,是因为类型维护了一个已登记方法的列表,事件发生后,类型将通知列表登记的所有方法: 事件模型建立在委托的基础上.委托是调用回调方法的一种类型安全的方式. 设计事 ...
- Scala学习笔记之Actor多线程与线程通信的简单例子
题目:通过子线程读取每个文件,并统计单词数,将单词数返回给主线程相加得出总单词数 package review import scala.actors.{Actor, Future} import s ...