ZR#955 折纸

解法:

可以发现折纸之后被折到上面的部分实际上是没有用的,因为他和下面对应位置一定是一样的,而影响答案的只有每个位置的颜色和最底层的坐标范围。因此,我们只需要考虑最底层即可,即我们可以把折纸等效为裁纸,每次去掉较小的那一部分。

用哈希维护每一列和每一行的极大回文子串,记录一下行与列的最大值相乘即可。

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath> using namespace std; #define LL long long
const int N = 2e6 + 50; char s[N],tt[N];
string p[N];
int HL[N],WL[N],m,n;
int HR[N],WR[N],t[N],f[N]; int manacher(int *p, char *ss, int Len) {
int len = 0; s[0] = '(';
for(int i = 1 ; i <= Len ; ++ i) {
s[++ len] = '#';
s[++ len] = ss[i];
}
s[++ len] = '#', s[++ len] = ')';
int mx = 0, id = 0;
for(int i = 1 ; i < len ; ++ i) {
if(i < mx) p[i] = min(mx - i, p[2 * id - i]);
else p[i] = 1;
while(s[i + p[i]] == s[i - p[i]]) ++ p[i];
if(i + p[i] > mx) mx = i + p[i], id = i;
}
return len;
} int main() {
scanf("%d%d",&n,&m);
for(int i = 1 ; i < n ; i++)
HL[i] = HR[i] = 1;
for(int i = 1 ; i < m ; i++)
WL[i] = WR[i] = 1;
for(int i = 1 ; i <= n ; i++)
cin >> p[i];
for(int i = 1 ; i <= n ; i++) {
int len = m;
for(int j = 1 ; j <= len ; j++)
tt[j] = p[i][j - 1];
int Len = manacher(t, tt, m) - 3;
int mx = 1;
for(int j = 3 ; j <= Len ; j += 2) {
if(j - t[j] + 1 <= mx) mx = j;
else WL[j >> 1] = 0;
}
int mn = Len + 2;
for(int j = Len ; j >= 3 ; j -= 2) {
if(j + t[j] - 1 >= mn) mn = j;
else WR[j >> 1] = 0;
}
}
LL ansW = 0;
int sum = 0;
WL[0] = 1, WR[m] = 1;
for(int i = 0 ; i <= m ; i++) sum += WR[i];
for(int i = 0 ; i <= m ; i++) {
if(WR[i]) -- sum;
if(WL[i]) ansW += sum;
}
swap(n, m);
for(int i = 1 ; i <= n ; i++) {
int len = m;
for(int j = 1 ; j <= len ; j++)
tt[j] = p[j][i - 1];
int Len = manacher(t, tt, m) - 3;
int mx = 1;
for(int j = 3 ; j <= Len ; j += 2) {
if(j - t[j] + 1 <= mx) mx = j;
else HL[j >> 1] = 0;
}
int mn = Len + 2;
for(int j = Len ; j >= 3 ; j -= 2) {
if(j + t[j] - 1 >= mn) mn = j;
else HR[j >> 1] = 0;
}
}
LL ansH = 0;
sum = 0;
HL[0] = 1, HR[m] = 1;
for(int i = 0 ; i <= m ; i++) sum += HR[i];
for(int i = 0 ; i <= m ; i++) {
if(HR[i]) -- sum;
if(HL[i]) ansH += sum;
}
printf("%lld\n", ansW * ansH);
//system("pause");
return 0;
}

ZR#955 折纸的更多相关文章

  1. CSS3写折纸

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

  2. 折纸问题java实现

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

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

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

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

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

  5. CSS3实现文字折纸效果

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

  6. 1074: [SCOI2007]折纸origami

    Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 372  Solved: 229[Submit][Status][Discuss] Descriptio ...

  7. UVA 177 PaperFolding 折纸痕 (分形,递归)

    著名的折纸问题:给你一张很大的纸,对折以后再对折,再对折……每次对折都是从右往左折,因此在折了很多次以后,原先的大纸会变成一个窄窄的纸条.现在把这个纸条沿着折纸的痕迹打开,每次都只打开“一半”,即把每 ...

  8. [CSP-S模拟测试]:折纸(模拟)

    题目描述 小$s$很喜欢折纸.有一天,他得到了一条很长的纸带,他把它从左向右均匀划分为$N$个单位长度,并且在每份的边界处分别标上数字$0\sim n$.然后小$s$开始无聊的折纸,每次他都会选择一个 ...

  9. 嵊州D5T2 折纸 folding

    折纸 folding [问题描述] 在非常紧张的 NOIP 考试中,有人喜欢啃指甲,有人喜欢转铅笔,有人喜欢撕 纸条,……而小 x 喜欢迷折纸. 现有一个 W * H 的矩形纸张,监考老师想知道,小 ...

随机推荐

  1. 数据结构-平衡二叉树Java实现

    1,Node.java package com.cnblogs.mufasa.BalanceBinaryTree; public class Node { Node parent; Node left ...

  2. Node在Sublime Text3下环境搭建(node02)

    一.下载sublime Text的nodejs插件 https://github.com/tanepiper/SublimeText-Nodejs 二.下载后解压 直接改名为nodejs 放到 Pre ...

  3. Oracle复习

    这阵子忙着面试 ,之前搞项目一直用的 mysql ,然后面试的大公司!(呵呵)偏偏用的是 oracle 没办法恶补 前面学过的但是没怎么用的Oracle 基础知识,打算主要从下面几点入手. 环境搭建: ...

  4. C#通过地址获取省市区(基于百度地图API)

    最近公司有个需求,想通过地址获取对应的省市区,本来想直接通过对地址的截取,对于完整的地址还可以,不完整的就没法用了 所以本篇通过百度地图API来获取地址 第一步:申请ak密钥 登录百度地图开放平台,按 ...

  5. lambda select和where区别

    本文用一个linq to xml语法作为示例,以下是用来操作的xml:<?xml version="1.0" encoding="utf-8" stand ...

  6. Unity 宽度适配 NGUI

    这是很久之前写的一篇Note,现在移到Blog上来,可能有些参数,NGUI插件等等不和现在版本相同.不过大概的思路应该不会错. ps: 可能有部分內容是摘抄自其他作者,没办法考证了,如有请务必联系我. ...

  7. Go 缓冲信道

    缓冲信道 语法结构:cap为容量 ch := make(chan type, cap) 缓冲信道支持len()和cap(). 只能向缓冲信道发送容量以内的数据. 只能接收缓冲信道长度以内的数据. 缓冲 ...

  8. 阿里P7告诉你什么是java并发包、线程池、锁

    并发包 java.util.concurrent从jdk1.5开始新加入的一个包,致力于解决并发编程的线程安全问题,使用户能够更为快捷方便的编写多线程情况下的并发程序. 同步容器 同步容器只有包括Ve ...

  9. linux centos安装nginx1.7.4

    原文转自 jerryhe326:https://www.cnblogs.com/jerrypro/p/7062101.html一.安装准备 首先由于nginx的一些模块依赖一些lib库,所以在安装ng ...

  10. Computer Vision_33_SIFT:Improving Bag-of-Features for Large Scale Image Search——2010

    此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...