首页 > 其他分享 >P3501 [POI2010] ANT-Antisymmetry 反对称 题解(字符串哈希+二分)

P3501 [POI2010] ANT-Antisymmetry 反对称 题解(字符串哈希+二分)

时间:2024-07-31 13:24:47浏览次数:14  
标签:mod1 mod2 01 int 题解 POI2010 mid ANT 字符串

原题

题意

若一个由 01 01 01组成的字符串将 0 0 0和 1 1 1取反,并倒过来后与原字符串相同,则称为反对称字符串。现在给你一个长度为 n ( n ≤ 1 0 5 ) n(n \le 10^5) n(n≤105) 01 01 01组成的字符串,求它有多少个反对称子串。(两个子串只要起始位置不同或长度不同就算做两个子串,即使子串的内容相同)

样例

8
11001011
7

思路

本文没有详细讲解字符串哈希的实现,不会戳这里

朴素

先预处理出原字符串的 H a s h Hash Hash数组和原字符串 01 01 01取反并前后颠倒的 H a s h Hash Hash数组,然后枚举每个子串,判断两个 H a s h Hash Hash是否相等,计数。复杂度 O ( n 2 ) O(n^2) O(n2),喜提TLE。

进阶

(此时我偷偷看了一下题目的标签,要用二分) 先考虑如何构造一个反对称字符串,如果没有“反”,那么就是回文串,很明显,是从中间开始,向两边扩展,对应位置的 01 01 01相同,例如: 01010 01010 01010和 11100111 11100111 11100111。但是要分成两种情况,奇数长度的字符串和偶数长度的字符串构造方法略有不同。可是有“反”,也就是说对应位置不是相同,而是相反。带到样例里算一下,比如说 001011 001011 001011,构造过程如下: 10 10 10 -> 0101 0101 0101 -> 001011 001011 001011。进一步发现,每一步都会构成一个反对称字符串,这就给二分提供了基础。

实现

可以枚举每个反对称子串中间两个位置的右边那个(这里需要注意一个细节,其实完全不用分两种情况,因为对应位置的字符不同,如果长度是奇数,中间的字符不可能和自己不同,所以长度只能是偶数),用二分找到最大的反对称字符串长度(实际的长度是 2 ⋅ m i d 2·mid 2⋅mid,这里枚举半边的长度),判断时看 i − m i d i-mid i−mid到 i + m i d − 1 i+mid-1 i+mid−1的子串是否是反对称串,如果是,就可以继续扩大长度判断,如果不是,由于中心确定,已经发现对应位置上的字符相同,不符合要求,再向两边扩大长度也不会成为反对称串,所以缩小长度。

代码

(本人为了保险,写了两个哈希表,其实一个也能过)

#include<bits/stdc++.h>
using namespace std;
#define mod1 1000000007
#define mod2 1000000009
#define mul 2
int n,a[500005];
long long h1[500005],h2[500005],g1[500005],g2[500005];
//h是原字符串,g是取反翻转后的
long long m1[500005],m2[500005],ans;
char s[500005];
int main(){
	scanf("%d%s",&n,s+1);
	m1[0]=m2[0]=1;
	for(int i=1;i<=n;i++) m1[i]=m1[i-1]*mul%mod1;
	for(int i=1;i<=n;i++) m2[i]=m2[i-1]*mul%mod2;
	for(int i=1;i<=n;i++) h1[i]=(h1[i-1]*mul%mod1+(s[i]=='1'))%mod1;
	for(int i=1;i<=n;i++) h2[i]=(h2[i-1]*mul%mod2+(s[i]=='1'))%mod2;
	for(int i=n;i>=1;i--) g1[i]=(g1[i+1]*mul%mod1+(s[i]=='0'))%mod1;
	for(int i=n;i>=1;i--) g2[i]=(g2[i+1]*mul%mod2+(s[i]=='0'))%mod2;
	for(int i=1;i<=n;i++){
		int l=1,r=min(i-1,n-i+1),flag=0;
		while(l<=r){
			int mid=(l+r)/2;
			int t1=(h1[i+mid-1]-h1[i-mid-1]*m1[2*mid]%mod1+mod1)%mod1,
			t2=(h2[i+mid-1]-h2[i-mid-1]*m2[2*mid]%mod2+mod2)%mod2,
			tt1=(g1[i-mid]-g1[i+mid]*m1[2*mid]%mod1+mod1)%mod1,
			tt2=(g2[i-mid]-g2[i+mid]*m2[2*mid]%mod2+mod2)%mod2;
			if(t1==tt1&&t2==tt2) l=mid+1,flag=1;
			else r=mid-1;
		}
		ans+=r;
	}
	printf("%lld\n",ans);
	return 0;
}

附赠如何见到祖宗的指南:
在这里插入图片描述

标签:mod1,mod2,01,int,题解,POI2010,mid,ANT,字符串
From: https://blog.csdn.net/2401_84512298/article/details/140817060

相关文章

  • ARC180 部分简要题解
    C设\(f_{i,j}\)为考虑前\(i\)个数,当前选出来的子序列和为\(j\)且强制最后一个选出来的数不为\(j\)的方案;设\(g_{i,j}\)为考虑前\(i\)个数,当前选出来的子序列和为\(j\)且强制最后一个选出来的数必为\(j\)的方案。注意到一个合法方案可以唯一与一个最后一个选出......
  • P10814 【模板】离线二维数点 题解
    题目传送门思路一眼主席树板子题,但是一看数据范围\(n,m\le2\times10^6\),似了。在线做法应该是似完了,考虑离线做法。我们知道树状数组是可以做二维偏序的,大家应该都知道一个经典问题:对于一个序列,多次询问下标\(\lea\)且数值\(\leb\)的数的个数。回到这道题,相比上面......
  • P2163 [SHOI2007] 园丁的烦恼 题解
    题目传送门题目大意:在一个平面直角坐标系上,给定\(n\)个点的坐标\((x,y)\),\(m\)次询问,每次询问一个矩形范围内的点的数量,此矩形用\(\{a,b,c,d\}\)来描述,其中\((a,b)\)为左下角,\((c,d)\)为右上角。思路:不难将题目转化为:给定一个长度为\(n\)的序列,序列中的每个元......
  • CF1997(edu168)题解 A-F
    A.StrongPassword注意到最大效果是在两个相同字符之间插入一个不同的,贡献为3。否则在一开始插入一个和首位不同的,贡献为2。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;voidsolve(){strings;cin>>s;boolok=0;for(inti......
  • 【题解】2024牛客多校第5场
    E安https://ac.nowcoder.com/acm/contest/81600/E分析简单博弈/思维题。当ai>bi时,当前骑士一定存活。当ai<bi时,当前骑士一定死亡。为了使得自己存活的骑士尽可能多,若存在ai=bi的情况,一定会选择令该骑士去攻击对方,并且双方均会轮流优先选择此类骑士。......
  • 【PlantSaver】电容式土壤湿度传感器使用及原理(并以Arduino实验)
    1.湿度检测原理关于这个传感器检测的原理,网上找的资料不多。类似传感器经典的设计是美国DECAGON公司生产的ECH2O系列传感器。其结构如下:式中:ε0=8.854×10-12为真空介电常数,单位F/m;S为板间遮盖面积,单位m2;C为板间电容量,单位F;δ为板件厚度,m;ε为含高湿敏性基......
  • 07-30 题解
    07-30题解A朴素的想法$dp(i,j,k)$表示考虑到第\(i\)位,前\(i\)位的和为\(j\),第\(i\)位的值为\(k\)然后咋转移?重新定义移动小球的方式:从自己右边的邻居拿过来正数个球拿过来负数个球(即往右边的邻居放正数个球)在第2种操作中,我们拿走的球会被后面放过来......
  • Luogu P1983 车站分级 题解 [ 绿 ] [ 拓扑排序 ] [ 图论建模 ] [ 虚点 ]
    车站分级:很好的拓扑排序题,细节有点多。图论建模首先观察对于一条线路,我们可以从中直接得到什么信息:假设这条线路的开头为\(st\),结尾为\(ed\),那么在\([st,ed]\)的车站中,没有被选入线路的点一定比选入线路的点的级数至少少\(1\)。对于这一点条件,我们就可以建模了。......
  • CF538H Summer Dichotomy 题解
    Description有\(T\)名学生,你要从中选出至少\(t\)人,并将选出的人分成两组,可以有某一组是空的。有\(n\)名老师,每名老师要被分配到两个小组之一,对于第\(i\)名老师,要求所在的小组中的学生人数\(\in[l_i,r_i]\)。此外,有\(m\)对老师不能在同一个小组中。你需要判断能否......
  • SP8099 TABLE - Crash´s number table 题解
    题目传送门前置知识一般的积性函数|数论分块|莫比乌斯反演解法令\(n\lem\)。考虑莫比乌斯反演,推式子,有\(\begin{aligned}&\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\operatorname{lcm}(i,j)\\&=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\frac{ij}{\gcd(i,j)......