[OpenJudge 3066]随机序列
[OpenJudge 3066]随机序列
试题描述
Bob喜欢按照如下规则生成随机数:
第一步:令a[0] = S, 当n = 0;
第二步:a[n+1] = (a[n]*A+B)%P;
第三步:如果a[n+1]在之前出现不超过两次,n = n + 1 并且转到第二步。
比如,如果S=4, A=2, B=1并且P=6,那么我们构建的序列是4,3,1,3,1
Bob认为两个随机产生的序列之前应该会有某种关联。所以他想知道这两个随机生成的序列的最长公共子序列。一个序列的子序列是指可以从该序列中删除某些元素(不改变剩余元素顺序)之后得到的序列。
输入
第一行包括一个整数T(T < 15),表示有多少组测试数据。
每一组测试数据包含两行,每一行都包含四个整数,分别是S, A, B 和 P,用来生成随机序列
0 < S,A,B,P < 200000.
输出
对于每一组测试数据,在一行中输出测试数据的序号以及最长公共子序列。请参照下面的输出样例。
输入示例
输出示例
Case :
Case :
Case :
数据规模及约定
见“输入”
题解
直接做 O(n2) 的 dp 显然是会 T 的,然而我们发现每个数至多出现两次,于是我们可以记下第一个数列中每个数出现的位置,把第二个数列中每个数转化成第一个中该数出现位置的降序排列,例如 a1 = { 4, 1, 3, 1, 3 },那么其中 4 的位置有 { 1 },1 的位置有 { 2, 4 },3 的位置有 { 3, 5 },那么如果 a2 = { 5, 2, 4, 1, 3, 4 },它就会被转化成 { 1, 4, 2, 5, 3, 1 } 这个样子。然后不难发现,转化后的数列求最长上升子序列就是答案了,时间复杂度可以做到 O(nlogn)。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std; const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
} #define maxn 400010
#define oo 2147483647
#define LL long long
int S, A, B, P, n, m, a1[maxn], a2[maxn<<1], pos[maxn][5], cnt[maxn], c2[maxn];
int f[maxn<<1], g[maxn<<1]; int main() {
int T = read(), kase = 0;
while(T--) {
memset(cnt, 0, sizeof(cnt));
memset(c2, 0, sizeof(c2));
S = read(); A = read(); B = read(); P = read();
a1[n = 1] = S; pos[a1[n]][++cnt[a1[n]]] = 1;
for(;;) {
a1[++n] = ((LL)a1[n-1] * A + B) % P;
if(cnt[a1[n]] >= 2){ n--; break; }
pos[a1[n]][++cnt[a1[n]]] = n;
}
// for(int i = 1; i <= n; i++) printf("%d ", a1[i]); putchar('\n');
S = read(); A = read(); B = read(); P = read();
int x = S;
m = 0;
for(int i = cnt[S]; i; i--) a2[++m] = pos[S][i];
for(;;) {
x = ((LL)x * A + B) % P;
if(c2[x] >= 2) break;
c2[x]++;
for(int i = cnt[x]; i; i--) a2[++m] = pos[x][i];
} for(int i = 1; i <= m; i++) g[i] = oo;
g[1] = a2[1];
int ans = 0;
for(int i = 2; i <= m; i++) {
int k = lower_bound(g + 1, g + m + 1, a2[i]) - g;
f[i] = k; ans = max(ans, f[i]);
g[k] = a2[i];
}
printf("Case %d: %d\n", ++kase, ans);
} return 0;
}
[OpenJudge 3066]随机序列的更多相关文章
- 【OpenJudge 8463】Stupid cat & Doge
http://noi.openjudge.cn/ch0204/8463/ 挺恶心的一道简单分治. 一开始准备非递归. 大if判断,后来发现代码量过长,决定大打表判断后继情况,后来发现序号不对称. 最后 ...
- 【OpenJudge 191】【POJ 1189】钉子和小球
http://noi.openjudge.cn/ch0405/191/ http://poj.org/problem?id=1189 一开始忘了\(2^{50}\)没超long long差点写高精度Q ...
- 【OpenJudge 1665】完美覆盖
http://noi.openjudge.cn/ch0405/1665/?lang=zh_CN 状压水题,手动转移 #include<cstdio> #include<cstring ...
- 【OpenJudge 1793】矩形覆盖
http://noi.openjudge.cn/ch0405/1793/ 好虐的一道题啊. 看数据范围,一眼状压,然后调了好长时间QwQ 很容易想到覆盖的点数作为状态,我用状态i表示至少覆盖状态i表示 ...
- OpenJudge 2990:符号三角形 解析报告
2990:符号三角形 总时间限制: 1000ms 内存限制: 65536kB 描述 符号三角形的第1行有n个由“+”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”+“ ...
- 随机序列生成算法---生成前N个整数的一组随机序列
问题描述: 给定输入N,生成从1开始的:1,2,3,4,......N 一组随机序列,序列中的数不能重复出现. 比如:N=5,合法的随机序列为{4,3,1,5,2} .{3,1,4,2,5}……非法的 ...
- OpenJudge 7624 山区建小学
在openjudge似乎无法凭题号搜到题...? 总时间限制: 1000ms 内存限制: 65536kB 描述 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任 ...
- [OpenJudge 3064]坠落的蚂蚁
[OpenJudge 3064]坠落的蚂蚁 试题描述 一根长度为1米的木棒上有若干只蚂蚁在爬动.它们的速度为每秒一厘米或静止不动,方向只有两种,向左或者向右.如果两只蚂蚁碰头,则它们立即交换速度并继续 ...
- [OpenJudge 3063]罪犯问题
[OpenJudge 3063]罪犯问题 试题描述 一天,警官抓获了N个嫌犯,审问N个罪犯的途中,作为警长助手的你突然发现其中被确定为罪犯的K号人是你曾经出生入死的兄弟,你不能眼睁睁看着他被抓进牢里. ...
随机推荐
- WCF入门(9)
前言 上次搬家空调出了点问题,和修空调的师傅商量了一下,感觉还是讲理的. 今天又在公司基本没有任何存在感的过了一天,纠结...领导还不在... 前些天往手机里面放了几集WCF入门视频,今天用暴风影音看 ...
- cursor:pointer的意思
cursor规则是设定网页浏览时用户鼠标指针的样式,也就是鼠标的图形形状cursor:pointer设定鼠标的形状为一只伸出食指的手,这也是绝大多数浏览器里面鼠标停留在网页链接上方时候的样式另外可以选 ...
- MyEclipse8.5快速搭建SSH框架
来源于:http://jingyan.baidu.com/article/a378c960a78125b3282830cc.html MyEclipse8.5快速搭建SSH框架 使用版本: Strut ...
- JS模式:Mixin混合模式,=_=!就是常见的Object.create()或者_extend()
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- java基础-关键字-native
一. 什么是Native Method 简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由 ...
- 【XDU1144】合并模板
问题 Fate 有 n 个 ACM/ICPC 比赛的模板,每个都是一个独立的 PDF 文件.为了便于打印,万神希望将这些模板合并成一个 PDF 文件.万神有一个工具,可以将至多 k 个 PDF 文件合 ...
- 未完结第八节 JBPM流程节点
1.12个节点介绍 2.Node节点
- 判断一个数据是否存在于一个表中,Oracle中写自定义函数
create or replace function isExist(data in DataTypes) --DataTypes 为表中该数据的类型return Numberisv_flag num ...
- 循序渐进Linux 3:Linux下软件安装与管理
一.源码安装 ./configuremakemake install 二.RPM包 1. 安装软件包 rpm -i [辅助选项] file1.rpm file2.rpm主选项 -i: install, ...
- tmux 快捷键
ctrl+b , 修改窗口名称 ctrl+b ' 快速按名字切换窗口 ctrl+b w 列出窗口列表 Ctrl+b 激活控制台:此时以下按键生效 系统操作 ? 列出所有快捷键:按q返回 d 脱离当前会 ...