Codeforces 1142B Lynyrd Skynyrd
---恢复内容开始---
题意:给你一个排列p和数组a,有t组询问,每次询问一个区间的子序列中是否有p的一个循环排列。
思路:以p = [3, 1, 2]举例, 我们扫描数组b,假设当前数字是1,那么我们找前面离现在最近的3的位置,然后连一条边。为什么只连最近的呢?比如[3,3,1,2]这种情况,1只需要和第二个3连就行了,因为连第一个3的这种情况已经被连第二个3的这种情况包含了。那么对于每个点,我们可以找到通过连的边走n - 1次所到的点,所有包含这个区间的询问区间都有一个合法的循环排列。但是直接暴力找n - 1次到的点会被卡成O(n^2)的,我们可以用倍增优化这个过程。之后,对于每个点,我们只需记录在它前面的点中满足走n - 1次的点中最大的那一个就行了,因为这样相当于对于每个点,尽力压缩合法的区间。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200010;
int f[maxn][20], pre[maxn], a[maxn], b[maxn], last[maxn], p[maxn], res[maxn];
int n, m, T, t;
int solve(int x) {
int now = n - 1, ans = x;
for (int i = t; i >= 0; i--) {
if(p[i] <= now) {
ans = f[ans][i];
now -= p[i];
}
}
return ans;
}
int main() {
int l, r;
scanf("%d%d%d", &n, &m, &T);
t = (int)(log(n) / log(2)) + 1;
p[0] = 1;
for (int i = 1; i <= t;i++) {
p[i] = p[i - 1] * 2;
}
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
for (int i = 2; i <= n; i++) {
pre[a[i]] = a[i - 1];
}
pre[a[1]] = a[n];
for (int i = 1; i <= m; i++) {
scanf("%d", &b[i]);
f[i][0] = last[pre[b[i]]];
for (int j = 1; j <= t; j++) {
f[i][j] = f[f[i][j - 1]][j - 1];
}
last[b[i]] = i;
}
int pos;
for (int i = 1; i <= m; i++) {
pos = solve(i);
res[i] = max(res[i - 1], pos);
}
while(T--) {
scanf("%d%d", &l, &r);
if(res[r] >= l) printf("1");
else printf("0");
}
}
---恢复内容结束---
Codeforces 1142B Lynyrd Skynyrd的更多相关文章
- CF1142E/1143B Lynyrd Skynyrd
CF1142E/1143B Lynyrd Skynyrd 开始读错题了,以为是连续的一段,敲完后才发现是 \(subsequence\) ... 考虑对于 \(a\) 中的每个 \(a_i\) 找到它 ...
- 【CF1142B】Lynyrd Skynyrd
[CF1142B]Lynyrd Skynyrd 题面 洛谷 题解 假设区间\([l,r]\)内有一个循环位移,那么这个循环位移一定有一个最后的点,而这个点在循环位移中再往前移\(n-1\)个位置也一定 ...
- 【题解】CF1142B Lynyrd Skynyrd(倍增)
[题解]CF1142B Lynyrd Skynyrd(倍增) 调了一个小时原来是读入读反了.... 求子段是否存在一个排列的子序列的套路是把给定排列看做置换,然后让给定的序列乘上这个置换,问题就转化为 ...
- 『题解』Codeforces1142B Lynyrd Skynyrd
更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description Recently Lynyrd and Skynyrd went to a ...
- B. Lynyrd Skynyrd
传送门: 题意:给出 n,m,q 然后给出模板串,从1-n数字只出现一次,然后给出长度为m的要询问的串. q组询问:每组询问输出 ‘1’或者‘0’ 每组询问 一对x,y 问在x到y中有没有模板串 ...
- Codeforces 1142B(倍增)
1.先预处理出在循环中某数前面的数是谁. 2.读入a数列时贪心选取最晚的父亲. 3.链上倍增预处理二进制祖先. 4.对于每个位置,预处理第n-1个祖先位置最早要从哪里开始,技巧上再顺手与前一位的最早位 ...
- CF1142B Lynyrd Skynyrd
题目 有两种做法: 第一种是\(O(nlog\ n)\)的. 我们预处理两个数组: \(pre_i\)表示\(p\)中\(i\)前面的那个数是\(pre_i\). \(lst_i\)表示\(a\)中\ ...
- 「CF1142B」Lynyrd Skynyrd
传送门 Luogu 解题思路 发现一个性质: 对于排列的任何一个循环位移,排列中的同一个数的前驱肯定是不变的. 而且,如果一个排列的循环位移是某一个区间的子序列,那么这个循环位移的结尾的 \(n-1\ ...
- Codeforces Round #549 (Div. 1)
今天试图用typora写题解 真开心 参考 你会发现有很多都是参考的..zblzbl Codeforces Round #549 (Div. 1) 最近脑子不行啦 需要cf来缓解一下 A. The B ...
随机推荐
- hive_学习_02_hive整合hbase(失败)
一.前言 本文承接上一篇:hive_学习_01_hive环境搭建(单机) ,主要是记录 hive 整合hbase的流程 二.环境准备 1.环境准备 操作系统 : linux CentOS 6.8 jd ...
- 条款47:请使用traits class表示类型信息
在stl的算法中,我们的希望往往是根据不同的迭代器类型进行不同的更有效率的操作: template<typename IterT, typename DistT> void advance ...
- fiddler抓包
1.fiddler安装 下载exe安装文件,傻瓜式安装 2.fiddler配置 点击Tools -->Telerik Fiddler Options -->Https,进入以下对话框 Ht ...
- 2017-2018-1 20179215《Linux内核原理与分析》第十二周作业
Sql注入基础原理介绍 分组:和20179205王雅哲共同完成实验 一.实验说明 1.1 sql注入 SQL注入攻击通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组 ...
- Linux命令学习(20):traceroute命令
版权声明 更新:2017-06-13博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下面的mv命令. 2 ...
- 使用.NET中的XML注释(二) -- 创建帮助文档入门篇
一.摘要 在本系列的第一篇文章介绍了.NET中XML注释的用途, 本篇文章将讲解如何使用XML注释生成与MSDN一样的帮助文件.主要介绍NDoc的继承者:SandCastle. 二.背景 要生成帮助文 ...
- 终于解决了一个Win7 下 VS 编译的问题,困扰了我好几个月
用 Win7 一年多了,一直在这个环境下编程,其他都挺好,就是有个问题非常恶心,在VS下编译经常出现进程正在使用,无法覆盖的错误,这个问题我记得博问中以前也有其他人遇到过,也没有解决掉.此问题困扰了我 ...
- Angular5学习笔记 - 服务优化(十)
一.服务合并 二.验证效果
- 操作Oracle 一条龙
1 引用Oracle.DataAccess.dll 2 App.Config中配置连接字符串: Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TC ...
- POJ2536(二分图最大匹配)
Gopher II Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8504 Accepted: 3515 Descrip ...