CF213E Two Permutations 线段树维护哈希值

当初竟然看成子串了$qwq$,不过老师的$ppt$也错了$qwq$



由于子序列一定是的排列,所以考虑插入$1$到$m$到$n-m+1$到$n$;

如何判断呢?可以用哈希$qwq$;

我们用线段树维护哈希值,合并时用就把左子树的哈希值$x[ls]$在$B$进制下左移$sum[rs]$位,即$x[tr]=x[ls]*p[sum[rs]]+x[rs]$;

此时就可以向上更新哈希值。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define ull unsigned long long
#define ll long long
#define R register int
#define md ((l+r)>>1)
#define ls (tr<<1)
#define rs (tr<<1|1)
#define pause (for(R i=1;i<=10000000000;++i))
#define OUT freopen("out.out","w",stdout)
using namespace std;
namespace Fread {
    static char B[1<<15],*S=B,*D=B;
    #define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
    inline int g() {
        R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==‘-‘?-1:fix;
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
    } inline bool isempty(const char& ch) {return ch<=36||ch>=127;}
    inline void gs(char* s) {register char ch; while(isempty(ch=getchar())); do *s++=ch; while(!isempty(ch=getchar()));}
}using Fread::g; using Fread::gs;
const int B=23,N=200010;
int n,m,s[N],a[N],pos[N],ans;
ull x[N<<2],sum[N<<2],p[N],cnt,hsh;
inline void upd(int tr,int l,int r) {
    sum[tr]=sum[ls]+sum[rs];
    x[tr]=x[ls]*p[sum[rs]]+x[rs];
}
inline void change(int tr,int l,int r,int pos,int d) {
    if(l==r) {sum[tr]+=(d?1:-1); x[tr]=d; return ;}
    if(pos<=md) change(ls,l,md,pos,d);
    else change(rs,md+1,r,pos,d); upd(tr,l,r);
}
signed main() {
#ifdef JACK
    freopen("NOIPAK++.in","r",stdin);
#endif
    m=g(),n=g(); p[0]=1; for(R i=1;i<=m;++i) p[i]=p[i-1]*B;
    for(R i=1;i<=m;++i) s[i]=g(),hsh=hsh*B+s[i],cnt+=p[i-1];
    for(R i=1;i<=n;++i) a[i]=g(),pos[a[i]]=i;
    for(R i=1;i<=n;++i) {
        if(i>m) change(1,1,n,pos[i-m],0);
        change(1,1,n,pos[i],i);
        R d=i-m; if(d>=0&&x[1]==d*cnt+hsh) ++ans;
    } printf("%d\n",ans);
} 


2019.06.15

原文地址:https://www.cnblogs.com/Jackpei/p/11029377.html

时间: 2024-11-03 20:20:20

CF213E Two Permutations 线段树维护哈希值的相关文章

最敏捷的机器人(线段树维护区间最值)

题面: Wind设计了很多机器人.但是它们都认为自己是最强的,于是,一场比赛开始了--机器人们都想知道谁是最敏捷的,于是它们进行了如下一个比赛.首先,他们面前会有一排共n个数,它们比赛看谁能最先把每连续k个数中最大和最小值写下来,当然,这些机器人运算速度都很,它们比赛的是谁写得快.但是Wind也想知道答案,你能帮助他吗? Input: 每组测试数据 第1行为n,k(1<=k<=n<=100000) 第2行共n个数,为数字序列,所有数字均在int范围内. Output: 共n-k+1行 第

zoj 3888 Twelves Monkeys 二分+线段树维护次小值

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3888 Twelves Monkeys Time Limit: 5 Seconds      Memory Limit: 32768 KB James Cole is a convicted criminal living beneath a post-apocalyptic Philadelphia. Many years ago, the Earth's surf

cf213E 线段树维护hash

链接 https://codeforces.com/contest/213/problem/E 题目大意 给出两个排列a.b,长度分别为n.m,你需要计算有多少个x,使 得\(a_1 + x; a_2 + x; a_3 + x... a_n + x\) 是b 的子序列(不连续的那种). 思路 巧妙啊 暴力直接扫会T 我们构造一个c数组,使得c[b[i]]=i 这样x+1到x+1+n就是一段连续的区间了233 插回去看看他们相对大小是不是和a数组相同 因为不连续所以线段树维护hash值,线段树按照

2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数

肯定先无脑树链剖分,然后线段树维护一段区间不同个数,再维护一个左右端点的费用. 线段树更新,pushDown,pushUp的时候要注意考虑链接位置的费用是否相同 还有就是树链剖分操作的时候,维护上一个更新的位置的费用. 总之就是出现区间合并,就考虑总数是否要减一 好想不好写 //场上根本写不完啊 1 /*--------------------------------------------------------------------------------------*/ 2 3 #inc

[BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】

题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经典模型. 我们线段树的一个节点表示一个区间的联通性,有 6 个 bool 值,表示这个区间的 4 个角上的点之间的联通性. 然后用两个子区间的联通性和两个子区间之间的连边情况合并出整个区间的联通性. 修改某条边时,先在边的数组中修改,然后从这条边所在的点的线段树叶子开始向上 Update . 询问两

CodeForces 343D 线段树维护dfs序

给定一棵树,初始时树为空 操作1,往某个结点注水,那么该结点的子树都注满了水 操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了 操作3,询问某个点是否有水 我们将树进行dfs, 生成in[u], 访问结点u的时间戳,out[u],离开结点u的时间戳 每个结点的in值对应在线段树中的区间的一点 那么对于操作1, 只要将区间[in[u],out[u]] 的值都改为1, 但是如果区间[in[u],out[u]] 原先存在为0的点,那么父区间肯定是空的,这个操作不能 改变父区间的状态,所以需要

Codeforces GYM 100114 D. Selection 线段树维护DP

D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Description When selecting files in an application dialog, Vasya noted that he can get the same selection in different ways. A simple mouse click selects a sing

HDU3973 线段树 + 字符哈希

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3973 , 线段树 + 字符哈希,好题. 又学了一种新的哈希方法,hhhh~ 解法: 想法是用P进制的数来表示一个字符串,由于可能数太大,所以就将转换成是十进制后的数模long long的最大值,这样虽然也有可能冲突,但是概率会非常小.这里的P可以随意取一个素数(我取的是31). 先用上面提到的哈希方法将W集合中的字符串都转成十进制数存在数组中,然后进行排序:每一次询问时候,将询问区间的子串转成十进制

Subsequence Count 2017ccpc网络赛 1006 dp+线段树维护矩阵

Problem Description Given a binary string S[1,...,N] (i.e. a sequence of 0's and 1's), and Q queries on the string.There are two types of queries:1. Flipping the bits (i.e., changing all 1 to 0 and 0 to 1) between l and r (inclusive).2. Counting the