[线段树 哈希] BalkanOI 2016. Haker

11.1.4 蓝桥杯树形结构之线段树之维护哈希 线段树维护哈希是解决一系列复杂区间问题的高效方法,尤其适用于需要快速验证区间数据唯一性或相等性的场景。通过结合线段树和哈希技术,我们不仅能高效处理区间操作,还能快速完成数据验证,是蓝桥杯等算法竞赛中的重要技术之一。掌握这一技巧,将在解决相关问题时为你带来显著的优势。 阅读详情

题目是给定一个字符串,有三种操作.

一种是询问两个子串是否相同

一种是区间内的 a 变成 b,b变成 c … z 变成 a

一种是区间 [L,R] 变成原串的区间 [k,k+R−L] 的子串

因为要判断是否相同,肯定就要HASH,因为第二种操作,要记一下每个字母出现的位置的hash值

第三种操作的话,用前缀和记一下原串的hash,打一个标记就好了

复杂度 O(nlogn×|∑|)

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

typedef unsigned long long ll;

const int N=100010,AB=26,ibase=31;

int n,m;
char a[N];
ll iHash[N<<2][AB+5],pw[N];
int cir[N<<2],bck[N<<2],b[N<<2],e[N<<2];
ll pre[N][AB+5];

inline ll Ghash(ll *g){
    ll ret=0;
    for(int i=0;i<AB;i++) ret+=g[i]*(i+1);
    return ret;
}

inline void toBack(int g,int k){
    cir[g]=0; ll *G=iHash[g];
    for(int i=0;i<AB;i++)   
        G[i]=pre[k+e[g]-b[g]][i]-pre[k-1][i]*pw[e[g]-b[g]+1];
    bck[g]=k;
}

ll tmp[AB];

inline void toCir(int g,int x){
    ll *G=iHash[g],lst=G[AB-1]; x%=26;
    for(int i=AB-1;~i;i--) tmp[i]=G[i-x<0?i-x+26:i-x];
    for(int i=0;i<AB;i++) G[i]=tmp[i];
    cir[g]+=x;
}

inline void Push(int g){
    int mid=b[g]+e[g]>>1;
    if(bck[g])
        toBack(g<<1,bck[g]),toBack(g<<1|1,bck[g]+mid-b[g]+1);
    if(cir[g]) 
        toCir(g<<1,cir[g]),toCir(g<<1|1,cir[g]);
    bck[g]=cir[g]=0;
}

inline void Up(int g){
    ll prod=pw[e[g]-(b[g]+e[g]>>1)];
    ll *G=iHash[g],*ls=iHash[g<<1],*rs=iHash[g<<1|1];
    for(int i=0;i<AB;i++)
        G[i]=ls[i]*prod+rs[i];
}

inline ll Query(int g,int L,int R,int l,int r){
    if(L==l && r==R) return Ghash(iHash[g]);
    int mid=L+R>>1; Push(g);
    if(r<=mid) return Query(g<<1,L,mid,l,r);
    else if(l>mid) return Query(g<<1|1,mid+1,R,l,r);
    else return Query(g<<1,L,mid,l,mid)*pw[r-mid]+Query(g<<1|1,mid+1,R,mid+1,r);
}

inline void Back(int g,int L,int R,int l,int r,int k){
    if(L==l && r==R) return toBack(g,k);
    int mid=L+R>>1; Push(g);
    if(r<=mid) Back(g<<1,L,mid,l,r,k);
    else if(l>mid) Back(g<<1|1,mid+1,R,l,r,k);
    else Back(g<<1,L,mid,l,mid,k),Back(g<<1|1,mid+1,R,mid+1,r,k+mid-l+1);
    Up(g);
}

inline void Cirs(int g,int L,int R,int l,int r){
    if(L==l && r==R) return toCir(g,1);
    int mid=L+R>>1; Push(g);
    if(r<=mid) Cirs(g<<1,L,mid,l,r);
    else if(l>mid) Cirs(g<<1|1,mid+1,R,l,r);
    else Cirs(g<<1,L,mid,l,mid),Cirs(g<<1|1,mid+1,R,mid+1,r);
    Up(g);
}

void Build(int g,int l,int r){
    b[g]=l; e[g]=r;
    if(l==r){
        iHash[g][a[l]-'a']=1; return ;
    }
    int mid=l+r>>1;
    Build(g<<1,l,mid); Build(g<<1|1,mid+1,r);
    Up(g);
}

inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}

inline void rea(int &x){
    char c=nc(); x=0;
    for(;c>'9' || c<'0';c=nc()); for(;c>='0' && c<='9';x=x*10+c-'0',c=nc());
}

inline int rea(char *x){
    char c=nc(); int len=0;
    for(;c>'z' || c<'a';c=nc()); for(;c>='a' && c<='z';x[++len]=c,c=nc()); return len;
}

int main(){
    n=rea(a); pw[0]=1;
    for(int i=1;i<=n;i++){
        for(int j=0;j<AB;j++)
            pre[i][j]=pre[i-1][j]*ibase;
        pre[i][a[i]-'a']++;
        pw[i]=pw[i-1]*ibase; 
    }
    Build(1,1,n);
    rea(m);
    while(m--){
        int opt,x,y,k;
        rea(opt); rea(x); rea(y);
        if(opt==1){
            rea(k);
            //ll cur=Query(1,1,n,2,3);
            puts(Query(1,1,n,x,y)==Query(1,1,n,k,k+y-x)?"Y":"N");
        }
        else if(opt==2){
            rea(k); Back(1,1,n,x,y,k); 
        }
        else Cirs(1,1,n,x,y);
        //for(int i=1;i<=n;i++) putchar(Query(1,1,n,i,i)+'a'-1); putchar('\n');
    }
}
7.3.6 蓝桥杯基础数据结构之线段树维护哈希 线段树维护哈希是处理字符串和序列数据区间问题的强大技术。它结合了线段树的高效区间管理和哈希的快速查询优势,适用于各种复杂的数据处理场景,尤其在编程竞赛中表现出色。 阅读详情

相关推荐

安卓无障碍服务保活实战:如何用AccessibilityService实现后台常驻(附完整代码)

本文深入解析如何利用Android无障碍服务(AccessibilityService)实现后台服务保活,涵盖多版本系统适配、前台服务集成、开机自启机制等关键技术。通过详细的Kotlin代码示例和合规性指导,帮助开发者构建稳定可靠的后台服务解决方案,同时避免因滥用无障碍服务导致的应用下架风险。

milk5的博客 1071

2020威海-Caesar Cipher-(线段树+hash修改)

G 题意: 就是给你一个数组,然后有两种操作,第一个就是让一段区间加1,然后如果这个数>65535了就变成0,然后第二个就是查询两端区间序列是否相同。 思考: 很明显的线段树,然后对数组维护一个hash,对了取模的话自己定义一个取模,不要用ull,因为出题人想卡你就卡你。现在难点就是维护hash的同时如何操作一段区间加1?其实发现∑ a[i] * base ^ i,现在每个a都加1,那么变化值就是​∑ base ^ i,所以维护一个pre对bas进行前缀和就行了。然后还有一个点就是对于如果这个数&gt

m0_52398496的博客 279

避坑指南:时间序列互相关分析(CCF)常见的5个误用场景

本文详细解析了时间序列互相关分析(CCF)中常见的5个误用场景,包括忽视平稳性检验、混淆同期相关与因果关联、误读滞后阶数、忽略自相关干扰以及样本量不足等问题。通过实际案例和技术建议,帮助数据分析师避免这些陷阱,确保CCF分析的准确性和可靠性。

weixin_29064009的博客 428

[BalkanOI2016]Cruise

题目大意:   平面直角坐标系内有n个点,每个点有一个点权。   你从原点p出发,走若干个点然后回到原点。   两个点之间只能笔直走,你的收获为你的路径围起来的区域内的所有店权和除以路径长度。   问最大收益。 思路:   不难发现:每走一步,相当于在路径形成的多边形中增加一个三角形。   我们可以预处理出所有这样以p为顶点的三角形内的点权和。   首先对于所有的点极角排序。...

weixin_33725272的博客 184

UserWarning: CUDA initialization: Unexpected error from cudaGetDeviceCount()【已解决】

UserWarning: CUDA initialization: Unexpected error from cudaGetDeviceCount()【已解决】

围炉夜敲的博客 1万+

别再硬啃理论了!手把手教你用Simulink搭VSG并网模型,模拟线路故障(含三相故障模块详解)

本文提供了一份详细的Simulink VSG并网模型搭建指南,特别聚焦于三相故障模块的配置与仿真。通过逐步指导,帮助电力电子工程师掌握从基础电路搭建到复杂故障模拟的全流程,包括单相接地、两相短路等典型故障的波形分析与参数设置技巧,有效弥合理论与实践的鸿沟。

weixin_29057237的博客 317

Caesar Cipher(线段树维护哈希)

https://codeforces.com/gym/102798/problem/G 解题思路: 1.和普通线段树维护哈希不同的是,这里要求原数组对一个数模mod,观察发现区间一次只加1,线段树记录区间最大值,在查询时如果区间的最大值大于等于mod,重建这部分线段树。 2.其他部分和普通的线段树维护哈希就一样了,建议写双哈希,以免被卡。 Code: #include <iostream> #include <map> #include <set> #incl

g3125976202的博客 817

Labelme安装教程(附Anaconda安装教程)

本文详细介绍了如何安装Anaconda和Labelme,还提供了常见问题的解决建议。

HanYan_ing的博客 1万+

字符串哈希(线段树维护)

这一种直接暴力维护的正反哈希,一个左高右低,一个右高左低,相比较于第一种做法多了一个快速幂的log( 注意取mod,不然会wa)我们这里是左高右低,故是hash[ l ]=hash[ l ]*p[ r.len ]+hash[ r ];这一种做法就和正常的字符串哈希基本思想一样,都是h[r]=h[l-1]*p[r-l+1];且注意要query要先递归右子树,以便于先维护出右部分的len。

m0_73673533的博客 572

Weaxor勒索病毒实战分析:从加密算法到防御策略(附检测工具清单)

本文对Weaxor勒索病毒进行了深度实战剖析,详细拆解了其采用ChaCha20与AES-CTR的混合加密算法、横向移动手法及数据回传行为。文章重点分析了其密钥生成机制的“漏洞修复”,并提供了从主机加固、网络监控到基于IOC威胁狩猎的立体化企业级防御策略与检测工具清单。

weixin_29233333的博客 260

第12篇: COZE 实操【自动生成每日英语短视频】详细制作流程

通过以上详细流程,你可以利用 Coze 智能体高效生成每日英语短视频。在实际操作中,若遇到问题或有新的创意需求,欢迎随时与我交流,进一步优化视频制作流程。从左侧节点库中拖拽 “开始” 节点到画布中央,设置主题输入框(如输入 “日常购物英语”),方便后续根据不同主题生成视频。2. 选题策划节点​。3. 内容生成节点​。4. 画面生成节点​。5. 配音生成节点​。6. 音频匹配节点​。7. 视频合成节点​。

AI实操部署-深耕AI领域老菜鸟! 2070

线段树维护字符串哈希

闲来补以前不会的题,打眼一看有了大致思路,写好大致的样子后,调了调一些bug,过了样例后提交,wa了。 昨晚改到现在,终于发现最终的两处错误在于,查询区间哈希值,二分查询最长长度。 第一处,查询[x,y]区间的哈希值,往下二分的时候,y的值不能直接代,要修改成mid才能往下代。因为两段字符串哈希值的合并,和后一段字符串的长度有关。 第二处,二分查找两个区间从左端点开始,能够匹配到的最长长度,可能存在两个左端点就不相等的情况,最后查询到的l的值是1,这时候就要特判1. #include <bits/st

ATXTKS的博客 749

PCL 使用点云创建数字高程模型DEM【2025最新版】

使用点云创建数字高程模型DEM,并将结果保存为高程图像。博客长期更新,本文最近更新时间为:2025年9月15日。

点云侠的博客 2294

24.8.18(线段树维护字符串哈希,警钟长鸣,百度之星打铁)

注意到最后一个数是可以最先得知的,即 a【i】+1,这题样例很好造,多造俩样例再观察下规律,就发现可以给已经填过的数加上1的权值,p【i】 不能一下得到答案,需要枚举check,若枚举到 j,查询在 p【i】后填过多少比 j小的数 (树状数组,a【i】代表在 p【i】前有多少小于等于 j的数 (经过++处理,若加起来后等于 j即满足,那么此数一定就是 j,复杂度感觉有点极限。二分时,如果枚举 i顺着放,冲突关系没有经过排序处理,会导致前面放的很随意,以至于后面遇到无法避免的大冲突,但其实是可以避免的。

breath_of_yuan的博客 1264

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

线段树+哈希【CF580E】Kefa and Watch

线段树+哈希【CF580E】Kefa and Watch Description \(n\)个数的字符串,\(m + k\)个操作 1 l r k把\(l - r\)赋值为\(k\) 2 l r d询问\(l - r\)是否有长度为\(d\)的循环节 \(n \leq 10^5, m + k \leq 10^5, d \leq 10\) Input 第一行为三个整数\(n,m,k\) 第二行为一...

weixin_30693683的博客 315

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

2020CCPC威海站 G Caesar Cipher (线段树维护哈希)

第一次做线段树维护哈希的题目 当做模板重点理解一下 题意:给定你n和q,然后给定你一个长度为n的序列,q次操作,每次操作有两种形式: 1 x y:代表从序列的第x项到第y项所有的(a[i] + 1) mod 65536 2 x y l:表示从询问分别以x和y为起点的两个序列,然后这两个序列是否完全相同,输出yes或no 思路:很明显我们看到区间操作[l,r]加一可以想到用线段树去操作,然后操作二是询问两个序列是否相等我们又可以想到是否可以用哈希去判断这两个序列是否是相等的。 具体实现: hash数组也就是.

forward77 499

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

算法课程笔记——线段树维护哈希

算法课程笔记——线段树维护哈希。

2302_79123319的博客 519

线段树+哈希好题——CF213E

考虑用一棵线段树来维护(平衡树也行),每次对于新的 a 排列,删除没用的数,加上新增的。2、得知x的情况下,这题是一个选取 b 序列中的部分数匹配 a 排列的问题。而匹配的问题解法无非那几种,再结合这里匹配的是子序列,有两个排列a和b,长度为n和m,现在将第一个排列的所有数字加上一个整数x,使得第一个排列为第二个排列的。1、x的改变是解决本题的一个难点,那我们可以考虑枚举x的值,以此排除x的影响 (这里用掉了n的复杂度)1、枚举x:由于序列 a 和 b 都为排列,所以 x 从0枚举到序列 b 的长度 m。

m0_71198491的博客 1451

[数论 拓展欧拉定理] BalkanOI 2016. Power-towers

题目大概是求这个东西模 mm由拓展欧拉定理ab≡⎧⎩⎨⎪⎪ab%ϕ(p)           gcd(a,p)=1ab                  gcd(a,p)≠1,b<ϕ(p)ab%ϕ(p)+ϕ(p)    gcd(a,p)≠1,b≥ϕ(p)   (modp)a^b\equiv \begin{cases}a^{b\%\phi(p)}~~~~~~~~~~~gcd(a,p)=1\\a^b~

CE玩家 558

[欧拉回路] 「Balkan OI 2016」Acrobat

一个图是欧拉图的充要条件是每个点度数是偶数且连通第一种操作是同时更改 aia_i 与 aja_j 的度数奇偶性,那么 aia_i 与 aja_j 之间连边,搞棵生成树,一个点的度数是奇数时就删去它与它父亲的边。然后用第二种操作把左边的点连通,再用第二种操作把左边度数为奇数的点连起来#include <cstdio> #include <iostream> #include <algorithm> #

CE玩家 449

[欧拉回路 dfs树] Balkan OI 2016 Acrobat

传送门:http://boi2016.ccs.org.cy/ 大概就是一个二分图 每次可以使一条xi-yj的边变换为xj-yi 或在y之间任意加边 使存在欧拉回路 我们可以先把x侧都度数为偶数 我们发现 对于xi-yj进行变换 xi yi xj yj 奇偶性都发生变化 然后呢 我们对 i-j 连边成为一个新图 那么就是找尽量少的边使每个点度数符合要求奇偶性 这个在任意一可生成树上贪心

雯舞 644

[二分答案 DP检验 几何] BalkanOI 2017. Cruise

题意是给定平面内2000给点(都在y轴右边),要选出一些点,和原点组成多边形,求在多边形内的点的点权和除以多边形周长的最大值。分数规划,二分答案∑wi∑disi,j≥mid{\sum w_i\over \sum dis_{i,j}}\ge mid∑w−mid∑disi,j≥0\sum w-mid\sum dis_{i,j}\ge 0这样求∑w−mid∑disi,j\sum w-mid\sum dis

CE玩家 731

【线段树哈希】「Balkan OI 2016」Haker

1A海星 题目大意 给你一个长度为 $n$ ,由小写字母构成的字符串 $S$ 和 $Q$ 个操作,每个操作是以下 3 种之一: 1 x y k :询问当前字符串从位置 $x$ 到 $y$ 的子串与从位置 $k$ 开始,长度为 $y-x+1$ 的子串是否相同。 2 x y k :将当前字符串从位置 $x$ 到 $y$ 的子串变成原始串从位置 $k$ 开始,长度为 $y−x+1$ ...

weixin_30765505的博客 221

Caesar Cipher(线段树 + 字符串哈希)

题目链接: Caesar Cipher 大致题意 给定一个非负整数序列, 有两种操作: 操作1: 将[l, r]区间所有数字+1, 操作2: 询问两个子序列区间是否相同. 特别的: 对于每一个数字, 应该为[0, 65535]之间的整数(%65536). 解题思路 区间修改+区间查询+询问子序列是否相同 ==> 线段树 + 字符串哈希 AC代码 #include <bits/stdc++.h> #define rep(i, n) for (int i = 1; i <= (n); +

Fau的博客 275

(AtCoder Beginner Contest 331) --- F - Palindrome Query -- -题解 (线段树 + 哈希)

那么题目要求对于某个点进行修改,然后查询这个区间是否是线段树,用到上一个性质,那我们可以发现这道题就是一个典型的单点修改+区间查询。如果 a1a2a3 是一个回文串,一定有 a1 * p * p + a2 * p + a3 == a1 + a2 * p + a3 * p * p,对于任意长度的回文串这个性质都是显然的。例如: ab + cd 这两个区间, ab的正哈希 为 a*p+b, cd的正哈希为c*p+d. abcd的正哈希为 a*p*p*p+ b*p*p + c*p+d,这样就可以看出规律了。

weixin_73936404的博客 710

ABC353 字符串哈希 线段树优化dp

哈希 字符串哈希问每个字符串和其他串的LCP的和。显然我们可以记录所有串的所有前缀的出现次数,可以用个哈希表存。然后我们枚举一个字符串的所有前缀,显然前缀个数随前缀变长是不增的。进一步,如果长度i的前缀个数为x,长度i1的前缀个数为y,那么和当前串LCP长度为i的串个数就是x−y,这样就能累加贡献了。需要注意的是我们不能直接把前缀字符串当成key,因为计算key的哈希值需要遍历字符串,不是O1的,也是On,当前缀很长时会超时。

Maxwell_Newton的博客 328
上一篇: [二分答案 DP检验 几何] BalkanOI 2017. Cruise
下一篇: [数论 拓展欧拉定理] BalkanOI 2016. Power-towers
LowestJN
博客等级 码龄10年 76粉丝 422原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值