CF452F Permutations/Luogu2757 等差子序列 树状数组、Hash
如果存在长度\(>3\)的等差子序列,那么一定存在长度\(=3\)的等差子序列,所以我们只需要找长度为\(3\)的等差子序列。可以枚举等差子序列的第二个元素\(b\),那么存在长度为\(3\)的等差子序列等价于:可以在\(b\)左边找到一个元素\(a\),在\(b\)右边找到一个元素\(c\),满足\(b - a = c - b\)。
对于找到\(ac\)两个元素,一个比较直观的想法是:对\(b\)左边和右边的所有元素各建一个bitset\(B1,B2\),对于某一个元素\(d \neq b\),如果\(d\)在\(b\)左边,那么\(B1[d]=1\),否则\(B2[d]=1\)。
不存在等差子序列意味着如果\(d\)在左边,则\(2 \times b - d\)一定不能在右边,反之同理。这等价于对于\([l,b-1](l \geq 1),[b + 1 , r](r \leq N)\),满足\(b - l = r - b\)时,有
\[B1[l,b-1] \lor rev(B2[b+1 , r]) = 2^{b - l} - 1\]
上面两个条件等价的原因是:若结果的第\(d\)位为\(0\),则\(B1[l,b-1]\)和\(rev(B2[b+1 , r])\)的第\(d\)位要么同时为\(0\),要么同时为\(1\)。若同时为\(0\)意味着\(b-d\)不在左边且\(b+d\)不在右边,同时为\(1\)意味着\(b-d\)在左边且\(b+d\)在右边,都存在等差子序列。如果其中有一个为\(0\),有一个为\(1\),\(b-d\)和\(b+d\)就会在同一边。
这样就可以从右往左枚举\(b\)的位置,动态维护\(B1,B2\)并查询。但是当数据范围到\(3 \times 10^5\)的时候bitset会TLE,这时可以使用Hash+树状数组维护与上面bitset意义相同的01串。复杂度变为\(O(nlogn)\)。
虽然CF是神机,但仍然需要注意常数。
//Luogu2757
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstdlib>
#include<algorithm>
#include<cstring>
//This code is written by Itst
using namespace std;
inline int read(){
int a = 0;
char c = getchar();
while(!isdigit(c)) c = getchar();
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return a;
}
#define st first
#define nd second
struct PII{
int first , second;
PII(int x = 0 , int y = 0):first(x) , second(y){}
bool operator ==(PII a){return a.st == first && a.nd == second;}
bool operator !=(PII a){return !(*this == a);}
};
const int MAXN = 1e4 + 7 , Base = 131 , MOD1 = 1e9 + 7 , MOD2 = 1e9 + 9;
PII powBs[MAXN] , sum[MAXN] , powInv[MAXN];
int arr[MAXN] , N , T;
bool f;
PII operator *(PII a , PII b){
return PII(1ll * a.st * b.st % MOD1 , 1ll * a.nd * b.nd % MOD2);
}
PII operator +(PII a , PII b){
PII t(a.st + b.st , a.nd + b.nd);
if(t.st >= MOD1) t.st -= MOD1;
if(t.nd >= MOD2) t.nd -= MOD2;
return t;
}
PII operator -(PII a , PII b){return a + PII(MOD1 - b.st , MOD2 - b.nd);}
struct BIT{
#define lowbit(x) (x & -x)
PII arr[MAXN];
BIT(){memset(arr , 0 , sizeof(PII) * (N + 1));}
void add(int pos , PII cur){
while(pos <= N){
arr[pos] = arr[pos] + cur;
pos += lowbit(pos);
}
}
PII get(int pos){
PII sum = PII(0 , 0);
while(pos){
sum = sum + arr[pos];
pos -= lowbit(pos);
}
return sum;
}
}Tree1 , Tree2;
inline int poww(long long a , int b , int MOD){
int times = 1;
while(b){
if(b & 1) times = times * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return times;
}
void init(){
powBs[0] = sum[0] = powInv[0] = PII(1 , 1);
for(int i = 1 ; i <= 10000 ; ++i){
powBs[i] = powBs[i - 1] * PII(Base , Base);
sum[i] = sum[i - 1] + powBs[i];
}
powInv[1] = PII(poww(Base , MOD1 - 2 , MOD1) , poww(Base , MOD2 - 2 , MOD2));
for(int i = 2 ; i <= 10000 ; ++i)
powInv[i] = powInv[i - 1] * powInv[1];
}
void work(){
for(int i = 1 ; i <= N ; ++i)
Tree1.add(arr[i] , powBs[arr[i]]);
for(int i = N ; i ; --i){
Tree1.add(arr[i] , PII(0 , 0) - powBs[arr[i]]);
if(arr[i] != 1 && arr[i] != N){
int l1 = 1 , r1 = arr[i] - 1 , l2 = arr[i] + 1 , r2 = N;
if(r2 - l2 < r1 - l1) l1 = r1 - (r2 - l2);
else r2 = l2 + (r1 - l1);
PII t = (Tree1.get(r1) - Tree1.get(l1 - 1)) * powInv[l1] + (Tree2.get(N + 1 - l2) - Tree2.get(N - r2)) * powInv[N - r2 + 1];
if(t != sum[r1 - l1]){
f = 1;
return;
}
}
Tree2.add(N - arr[i] + 1 , powBs[N - arr[i] + 1]);
}
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
init();
for(int T = read() ; T ; --T){
N = read();
f = 0;
for(int i = 1 ; i <= N ; ++i)
arr[i] = read();
Tree1 = BIT(); Tree2 = BIT();
work();
puts(f ? "Y" : "N");
}
return 0;
}
CF452F Permutations/Luogu2757 等差子序列 树状数组、Hash的更多相关文章
- bzoj 2124 等差子序列 树状数组维护hash+回文串
等差子序列 Time Limit: 3 Sec Memory Limit: 259 MBSubmit: 1919 Solved: 713[Submit][Status][Discuss] Desc ...
- 【BZOJ2124】等差子序列 树状数组维护hash值
[BZOJ2124]等差子序列 Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N ...
- bzoj 1669: [Usaco2006 Oct]Hungry Cows饥饿的奶牛【dp+树状数组+hash】
最长上升子序列.虽然数据可以直接n方但是另写了个nlogn的 转移:f[i]=max(f[j]+1)(a[j]<a[i]) O(n^2) #include<iostream> #in ...
- bzoj2124 等差子序列(树状数组+hash)
题意 给你一个1~n排列,问有没有一个等差数列(长度至少为3) 题解 我居然自己想到了正解. 但我最后写挂了,所以我又看了题解. 我们维护了一个以权值为下标的01序列. 我们扫描整个序列.对于每一个正 ...
- 【bzoj5157】[Tjoi2014]上升子序列 树状数组
题目描述 求一个数列本质不同的至少含有两个元素的上升子序列数目模10^9+7的结果. 题解 树状数组 傻逼题,离散化后直接使用树状数组统计即可.由于要求本质不同,因此一个数要减去它前一次出现时的贡献( ...
- Maximum Subsequence Sum【最大连续子序列+树状数组解决】
Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i < ...
- bzoj5157: [Tjoi2014]上升子序列(树状数组LIS)
5157: [Tjoi2014]上升子序列 题目:传送门 题解: 学一下nlogn的树状数组求最长上生子序列就ok(%爆大佬) 离散化之后,用一个数组记录一下,直接树状数组做 吐槽:妈耶...一开始不 ...
- BZOJ2124: 等差子序列(树状数组&hash -> bitset 求是否存在长度为3的等差数列)
2124: 等差子序列 Time Limit: 3 Sec Memory Limit: 259 MBSubmit: 2354 Solved: 826[Submit][Status][Discuss ...
- BZOJ 3173 最长上升子序列(树状数组+二分+线段树)
给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? 由于序列是顺序插入的,所以当前插入的数字对之 ...
随机推荐
- UML简单介绍-如何看懂UML(一)
在计算复杂的数学题时,我们必然会打草稿计算 在绘画课中,我们可以素描出来看到的事物 那么在程序设计中呢? 如何描绘传达你脑海中的关于这个程序 ,设计的蓝图草稿? OOP的程序设计中,最多的自然 ...
- [十二]JavaIO之BufferedInputStream BufferedOutputStream
功能简介 BufferedInputStream 和 BufferedOutputStream一样,他们都是过滤流 装饰器模式下具体的装饰类 用来装饰InputStream以及OutputStream ...
- [二十二]JavaIO之LineNumberReader
功能介绍 LineNumberReader是提供了行号的具体的装饰器类 跟踪行号的缓冲字符输入流 此类定义了方法 setLineNumber(int) 和 getLineNumber(),它们可分别用 ...
- 痞子衡嵌入式:第一本Git命令教程(7.1)- 清理之缓存(stash)
今天是Git系列课程第七课,上一课我们学会了查看Git本地历史提交,今天痞子衡要讲的是Git仓库的清理操作,一共4个命令,都是日常开发中非常实用的命令,掌握这4个命令,会让你有一种玩弄Git仓库于股掌 ...
- spring学习(五) ———— 整合web项目(SSM)
一.SSM框架整合 1.1.整合思路 从底层整合起,也就是先整合mybatis与spring,然后在编写springmvc. 1.2.开发需求 查询商品列表(从数据库中查询) 1.3.创建web工程 ...
- 关于 vue 不能 watch 数组变化 和 对象变化的解决方案
原文地址:关于 vue 不能 watch 数组变化 和 对象变化的解决方案 vue 监听数组和对象的变化 vue 监听数组 vue 实际上可以监听数组变化,比如: data () { return { ...
- [ASP.NET] ASP.NET Identity 中 ClaimsIdentity 解析
各位好 : ) 最近筆者在嘗試改用ASP.NET Identity做為新系統的認證方式,發現到網路上給的資訊,不是很完整,所以做為一個工程屍,為了避免大家遇到一樣的問題.特地將一些有趣的地方記錄下來 ...
- WPF 文本框设置了阴影效果后,因左右的transform变化引发的拉伸渲染问题
背景 最近遇到一个动画执行时,文本位置变化的问题.如下图: 如果你仔细看的话,当星星变小时,文本往下降了几个像素. 貌似有点莫名其妙,因为控件之间并不在同一个Panel布局控件中,不存在高度限制变化引 ...
- Mac下如何用SSH连接远程Linux服务器
终端命令 a).打开Mac的命令终端 b).输入ssh -p 22 root@102.210.86.213 它会提示你输入密码,输入正确的密码之后,你就发现已经登陆成功了.(22: 端口号 root ...
- [Go] golang缓冲通道实现管理一组goroutine工作
通道1.当一个资源需要在goroutine之间共享时,通道在goroutine之间架起了一个管道2.无缓冲通道和有缓冲通道,make的第二个参数就是缓冲区大小3.无缓冲通道需要发送和接收都准备好,否则 ...