MemSQL Start[c]UP 2.0 - Round 1 F - Permutation 思维+线段树维护hash值

news/2024/7/8 4:26:09

F - Permutation

思路:对于当前的值x, 只需要知道x + k, x - k这两个值是否出现在其左右两侧,又因为每个值只有一个,

所以可以转换成,x+k, x-k在到x所在位置的时候是否都出现,或者都不出现,即出现情况相等,我们可以

用线段树维护hash值的方式来判断所有x+k,  x-k的出现情况是否都一样。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define PLI pair<LL, int>
#define ull unsigned long long
using namespace std;

const int N = 3e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;

int n;
ull Pow[N];
struct segmentTree {
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
    struct info1 {
        ull hs; int len;
        info1 operator + (const info1 &rhs) {
            return info1{hs+rhs.hs*Pow[len], len+rhs.len};
        }
    } a[N<<2];
    struct info2 {
        ull hs; int len;
        info2 operator + (const info2 &rhs) {
            return info2{rhs.hs+hs*Pow[rhs.len], len+rhs.len};
        }
    } b[N<<2];
    void build(int l, int r, int rt) {
        if(l == r) {
            a[rt] = info1{0, 1};
            b[rt] = info2{0, 1};
            return;
        }
        int mid = l + r >> 1;
        build(lson); build(rson);
        a[rt] = a[rt<<1] + a[rt<<1|1];
        b[rt] = b[rt<<1] + b[rt<<1|1];
    }
    void update(int p, int l, int r, int rt) {
        if(l == r) {
            a[rt] = info1{1, 1};
            b[rt] = info2{1, 1};
            return ;
        }
        int mid = l + r >> 1;
        if(p <= mid) update(p, lson);
        else update(p, rson);
        a[rt] = a[rt<<1] + a[rt<<1|1];
        b[rt] = b[rt<<1] + b[rt<<1|1];
    }
    info1 querya(int L, int R, int l, int r, int rt) {
        if(l >= L && r <= R) return a[rt];
        int mid = l + r >> 1;
        if(R <= mid) return querya(L, R, lson);
        else if(L > mid) return querya(L, R, rson);
        else return querya(L, R, lson) + querya(L, R, rson);
    }
    info2 queryb(int L, int R, int l, int r, int rt) {
        if(l >= L && r <= R) return b[rt];
        int mid = l + r >> 1;
        if(R <= mid) return queryb(L, R, lson);
        else if(L > mid) return queryb(L, R, rson);
        else return queryb(L, R, lson) + queryb(L, R, rson);
    }
} seg;

int main() {
    for(int i=Pow[0]=1; i < N; i++) Pow[i]=Pow[i-1]*131;
    scanf("%d", &n);
    seg.build(1, n, 1);
    bool flag = false;
    for(int i = 1; i <= n; i++) {
        int x; scanf("%d", &x);
        int len = min(x-1, n-x);
        if(len && seg.querya(x-len, x-1, 1, n, 1).hs != seg.queryb(x+1, x+len, 1, n, 1).hs)
            flag = true;
        seg.update(x, 1, n, 1);
    }
    if(flag) puts("YES");
    else puts("NO");
    return 0;
}

/*
*/

 

转载于:https://www.cnblogs.com/CJLHY/p/9895664.html


http://www.niftyadmin.cn/n/4556919.html

相关文章

什么是索引?

最常见的索引类型涉及单个列&#xff0c;将来自该列的值的副本存储在数据结构中&#xff0c;从而允许快速查找具有相应列值的行。B树数据结构让索引可以快速找到一个特定的值&#xff0c;一组值&#xff0c;或者一个范围内的值&#xff0c;对应于子句 中的运算符&#xff0c;如…

学c语言有什么用

自己查看看 ||| 基础性的语法 它适合作为系统描述语言 学学还是有必要的 为以后打基础 由于汇编语言依赖于计算机硬件 即可用来编写系统软件 C语言是国际上广泛流行的、很有发展前途的计算机高级语言 早期的操作系统等系统软件主要是用汇编语言编写的&#xff08;包括 UNIX操作…

Spire.Doc修改目录字体大小

官方论坛 官方论坛的解决方案&#xff1a; static void Main(string[] args){Document doc new Document();doc.LoadFromFile("目录.docx");foreach (Section section in doc.Sections){//遍历body下面所有对象foreach (DocumentObject obj in section.Body.ChildO…

分布式的演练、Zookeeper基本概念(一)

1、从集中式到分布式 在20世纪60年代大型主机被发明出来之后&#xff0c;凭借其超强的计算和io处理能力以及在稳定型和安全性方面的卓越表现&#xff0c;在很长的一段时间内&#xff0c;大型主机引领了计算机行业以及商业计算领域的发展&#xff0c;在大型主机的研发上最知名的…

C语言一共有哪32个关键字

声明无类型指针&#xff08;基本上就这三个作用&#xff09; default&#xff1a;开关语句中的“其他”分支 goto&#xff1a;无条件跳转语句 sizeof&#xff1a;计算数据类型长度 volatile&#xff1a;说明变量在程序执行中可被隐含地改变 do &#xff1a;循环语句的循环体 wh…

Zookeeper安装、常用命令(二)

1、安装 1.1、需要环境jdk 1.2、解压 tar -zxvf zookeeper-3.4.6.tar.gz mv zookeeper-3.4.6/ zookeeper1.3、更名 cd /usr/local/zookeeper/conf cp zoo_sample.cfg zoo.cfg1.4、创建文件 mkdir -p /usr/local/datas/zookeeper mkdir -p /usr/local/logs/zookeeper1.5、…

在linux中根据pid杀死所有子进程/后代进程

杀死所有子进程&#xff1a; pkill -P $$$$ 为 目标 pid 另一种情况是你可能想要杀死当前 shell 进程的所有后代以及直接子进程。在这种情况下&#xff0c;你可以使用下面的递归 shell 函数列出所有后代 PID&#xff0c;然后将它们作为参数传递给 kill&#xff1a; list_des…

apt-get 常用命令总结

apt-get 高级包装工具&#xff08;英语&#xff1a;Advanced Packaging Tools,简称&#xff1a;APT&#xff09;是Debian及其衍生发行版&#xff08;如&#xff1a;ubuntu&#xff09;的软件包管理器。APT可以自动下载&#xff0c;配置&#xff0c;安装二进制或者源代码格式的…