正题

题目链接:https://www.ybtoj.com.cn/problem/526


题目大意

一个\(n\times m\)的网格上有字母,你每次可以沿平行坐标轴对折网格,要求对折的对应位置字母相同。

询问有多少个可能对折出来的子矩阵。

\(1\leq n\times m\leq 10^6\)


解题思路

首先行和列是独立的,行的对折不会和列的对折有任何关联,所以可以分开考虑行和列可以对折出的区间。

然后设每一行分开对每个轴求出一个最大对折距离(这个用二分+\(hash\)或者马拉车就可以求出来了),然后同位置的所有行取最小值就好了。

之后对于每个轴的位置就有一个可以转移过来的区间,而且左右的对折如果过头了不会影响答案(可以自己画个图,因为回文串的性质,那么两边一定可以先对折出一个更小不会冲突的区间)

维护一个前缀和就好了(考场上犯病写了个树状数组)

时间复杂度\(O(n\log n)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x&-x)
using namespace std;
const ll N=1e6+10;
const ull g=131;
ll n,m,t[N],ac[N],cr[N],dp[N],lim;
ull h[N],f[N],pw[N];
char c[N],*s[N];
void Change(ll x,ll val){
while(x<=lim){
t[x]+=val;
x+=lowbit(x);
}
return;
}
ll Ask(ll x){
ll ans=0;
while(x){
ans+=t[x];
x-=lowbit(x);
}
return ans;
}
ll Query(ll l,ll r)
{return Ask(r)-Ask(l-1);}
ull geth(ll l,ll r)
{return h[r]-h[l-1]*pw[r-l+1];}
ull getf(ll l,ll r)
{return f[l]-f[r+1]*pw[r-l+1];}
signed main()
{
freopen("paper.in","r",stdin);
freopen("paper.out","w",stdout);
scanf("%lld%lld",&n,&m);pw[0]=1;
for(ll i=1;i<=max(n,m);i++)
pw[i]=pw[i-1]*g;
memset(ac,0x3f,sizeof(ac));
memset(cr,0x3f,sizeof(cr));
s[1]=c-1;
for(ll p=1;p<=n;p++){
scanf("%s",s[p]+1);
for(ll i=1;i<=m;i++)
h[i]=h[i-1]*g+s[p][i]-'a';
for(ll i=m;i>=1;i--)
f[i]=f[i+1]*g+s[p][i]-'a';
for(ll i=2;i<=m;i++){
ll l=0,r=min(i-2,m-i);
while(l<=r){
ll mid=(l+r)>>1;
if(geth(i-mid-1,i-1)==getf(i,i+mid))l=mid+1;
else r=mid-1;
}
ac[i]=min(ac[i],r);
}
s[p+1]=s[p]+m;
}
f[n+1]=0;
for(ll p=1;p<=m;p++){
for(ll i=1;i<=n;i++)
h[i]=h[i-1]*g+s[i][p]-'a';
for(ll i=n;i>=1;i--)
f[i]=f[i+1]*g+s[i][p]-'a';
for(ll i=2;i<=n;i++){
ll l=0,r=min(i-2,n-i);
while(l<=r){
ll mid=(l+r)>>1;
if(geth(i-mid-1,i-1)==getf(i,i+mid))l=mid+1;
else r=mid-1;
}
cr[i]=min(cr[i],r);
}
}
lim=m;Change(1,1);dp[1]=1;
for(ll i=2;i<=m;i++){
bool tmp=(Query(i-ac[i]-1,i-1)!=0);
dp[i]=dp[i-1]+tmp;
if(tmp)Change(i,1);
} memset(t,0,sizeof(t));
Change(m,1);ll sum=dp[m];
for(ll i=m-1;i>=1;i--){
bool tmp=(Query(i+1,i+ac[i+1]+1)!=0);
if(tmp)sum+=dp[i],Change(i,1);
} memset(t,0,sizeof(t));
lim=n;Change(1,1);
for(ll i=2;i<=n;i++){
bool tmp=(Query(i-cr[i]-1,i-1)!=0);
dp[i]=dp[i-1]+tmp;
if(tmp)Change(i,1);
} memset(t,0,sizeof(t));
Change(n,1);ll ans=dp[n];
for(ll i=n-1;i>=1;i--){
bool tmp=(Query(i+1,i+cr[i+1]+1)!=0);
if(tmp)ans+=dp[i],Change(i,1);
}
printf("%lld\n",ans*sum);
return 0;
}

YbtOJ#526-折纸游戏【二分,hash】的更多相关文章

  1. 【bzoj3796】Mushroom追妹纸 Kmp+二分+Hash

    题目描述 给出字符串s1.s2.s3,找出一个字符串w,满足: 1.w是s1的子串: 2.w是s2的子串: 3.s3不是w的子串. 4.w的长度应尽可能大 求w的最大长度. 输入 输入有三行,第一行为 ...

  2. Solution -「LOCAL」「cov. HDU 6816」折纸游戏

    \(\mathcal{Description}\)   Link(削弱版).   \(n\) 张纸叠在一起对折 \(k\) 次,然后从上到下为每层的正反两面写上数字,求把纸重新摊平后每张纸上的数字序列 ...

  3. CSS3写折纸

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  4. BZOJ 1014: [JSOI2008]火星人prefix [splay 二分+hash] 【未完】

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6243  Solved: 2007[Submit] ...

  5. 折纸问题java实现

    /** * 折纸问题 这段代码写的太low了 本人水平有限 哎... 全是字符串了 * @param n * @return * @date 2016-10-7 * @author shaobn */ ...

  6. 【BZOJ】1074: [SCOI2007]折纸origami

    http://www.lydsy.com/JudgeOnline/problem.php?id=1074 题意:一开始有一个左上角是(0,100),右下角是(100,0)的纸片,现在可以沿有向直线折n ...

  7. 1074: [SCOI2007]折纸origami - BZOJ

    Description 桌上有一张边界平行于坐标轴的正方形纸片,左下角的坐标为(0,0),右上角的坐标为(100,100).接下来执行n条折纸命令.每条命令用两个不同点P1(x1,y1)和P2(x2, ...

  8. CSS3实现文字折纸效果

    CSS3实现文字折纸效果 效果图: 代码如下,复制即可使用: <!DOCTYPE html> <html> <head> <title></tit ...

  9. BZOJ1014: [JSOI2008]火星人prefix(splay 二分 hash)

    题意 题目链接 Sol 一眼splay + 二分hash,不过区间splay怎么写来着呀 试着写了两个小时发现死活不对 看了一下yyb的代码发现自己根本就不会splay.... // luogu-ju ...

随机推荐

  1. C# 异步锁 await async锁,lock,Monitor,SemaphoreSlim

    异步方法内无法使用Monitor 和lock 所以只能用System.Threading.SemaphoreSlim了 //Semaphore (int initialCount, int maxim ...

  2. COM笔记-COM库函数

    COM在OLE32.DLL和 OLE32.LIB定义了一些常用的函数.在使用这些函数前要先调用CoInitialize来初始化COM库.当进程不再需要使用COM库函数时要调用CoUninitializ ...

  3. redis知识点及常见面试题

    redis知识点及常见面试题 参考: https://zm8.sm-tc.cn/?src=l4uLj4zF0NCIiIjRnJGdk5CYjNGckJLQrIqNiZaJnpOWjIvQno2Llpy ...

  4. ajax无法返回视图

    $.ajax({ url:"http://localhost:8080/wb/toUpLoad", type:"post", data:formData, pr ...

  5. PyQt4制作GUI

    时间:2018-11-30 记录:byzqy 标题:PyQt4入门学习笔记(一) 地址:https://www.cnblogs.com/chuxiuhong/p/5865201.html 标题:PyQ ...

  6. roscore启动不完全问题

    运行roscore,得到如下日志,且一直卡着无法继续执行 ... logging to /home/xbit/.ros/log/79f2952c-589c-11ea-8213-d0abd5e7d222 ...

  7. iGuard和NFS文件同步的解决方案

    一般来说,从文件系统中获得文件变化信息,调用操作系统提供的 API 即可.Windows 操作系统上有个名为 ReadDirectoryChangesW 的 API 接口,只要监视一个目录路径就可以获 ...

  8. 一键备份公众号的所有文章到PDF,再也不用担心想看的文章被删了

    有的时候,我们会发现收藏的某个微信公众号文章会被删或者和谐了,尤其是对自己非常实用的文章,一定会后悔当初怎么没有复制或者备份下来. 单篇的公众号文章要备份,随便百度一下就能找到非常多方法,这里就不多废 ...

  9. JavaWeb使用Filter进行字符编码过滤 预防web服务中文乱码

    JavaWeb使用Filter进行字符编码过滤 预防web服务中文乱码 准备条件:一个创建好的 JavaWeb 项目 步骤: 1.创建一个类并实现 Filter 接口 import javax.ser ...

  10. Python习题集(八)

    每天一习题,提升Python不是问题!!有更简洁的写法请评论告知我! https://www.cnblogs.com/poloyy/category/1676599.html 题目 要求:判断数组元素 ...