题目链接:洛谷


首先我们不考虑本质不同这个限制。

既然不能直接用栈乱搞,我们就可以用一个前缀和的套路了。

我们将(设为1,将)设为-1,记前缀和为$s_i$,则$[i,j]$这一段是回文子串当且仅当

1.$s_j=s_{i-1}$

2.$\forall k\in [i,j],s_k\geq s_{i-1}$

于是我们枚举$i$,显然$j$要满足第二个性质就肯定不能超过一个上界,这个上界是可以二分的。每次check的时候就判断一下区间最小值,可以用ST表维护。

然后看看本质不同如何做。

这时候我们就要请出SA,求出$sa[]$和$ht[]$之后,枚举$sa[i]$作为左端点,此时必须$j\geq sa[i]+ht[i]$,其中$ht[]$是高度数组,否则就会与前面的字符串重复。

改一改二分的区间就可以了。

 #include<bits/stdc++.h>
#define Rint register int
using namespace std;
typedef long long LL;
const int N = ;
int n, a[N], m, sa[N], rak[N], tmp[N], c[N], *x = rak, *y = tmp, ht[N];
LL ans;
inline void Qsort(){
for(Rint i = ;i <= m;i ++) c[i] = ;
for(Rint i = ;i <= n;i ++) ++ c[x[y[i]]];
for(Rint i = ;i <= m;i ++) c[i] += c[i - ];
for(Rint i = n;i;i --) sa[c[x[y[i]]] --] = y[i];
}
inline void Ssort(){
m = ;
for(Rint i = ;i <= n;i ++){
x[i] = a[i]; y[i] = i;
}
Qsort();
for(Rint w = , p;w < n;w <<= , m = p){
p = ;
for(Rint i = n - w + ;i <= n;i ++) y[++ p] = i;
for(Rint i = ;i <= n;i ++) if(sa[i] > w) y[++ p] = sa[i] - w;
Qsort();
swap(x, y);
x[sa[]] = p = ;
for(Rint i = ;i <= n;i ++)
x[sa[i]] = (y[sa[i]] == y[sa[i - ]] && y[sa[i] + w] == y[sa[i - ] + w]) ? p : ++ p;
if(p >= n) break;
}
for(Rint i = ;i <= n;i ++) rak[sa[i]] = i;
int k = ;
for(Rint i = ;i <= n;i ++){
if(rak[i] == ) continue;
int j = sa[rak[i] - ];
if(k) -- k;
while(a[j + k] == a[i + k]) ++ k;
ht[rak[i]] = k;
}
}
int st[][N], lg2[N];
inline int query(int l, int r){
int k = lg2[r - l + ];
return min(st[k][l], st[k][r - ( << k) + ]);
}
vector<int> pos[N << ];
int main(){
scanf("%d", &n);
for(Rint i = ;i <= n;i ++){
int ch = getchar();
while(ch != '(' && ch != ')') ch = getchar();
a[i] = (ch == ')') + ;
}
Ssort();
st[][] = n;
for(Rint i = ;i <= n;i ++) st[][i] = st[][i - ] - a[i] * + ;
for(Rint i = ;i <= n;i ++) pos[st[][i]].push_back(i);
for(Rint i = ;i <= ;i ++)
for(Rint j = ;j <= n;j ++)
st[i][j] = min(st[i - ][j], st[i - ][j + ( << i - )]);
lg2[] = ;
for(Rint i = ;i <= n;i ++) lg2[i] = lg2[i >> ] + ;
for(Rint i = ;i <= n;i ++){
if(a[sa[i]] == ) continue;
int l = sa[i] + ht[i], r = n, mid, res = l - ;
while(l <= r){
mid = l + r >> ;
if(query(sa[i], mid) >= st[][sa[i] - ]){l = mid + , res = mid;}
else r = mid - ;
}
int t = st[][sa[i] - ];
ans += upper_bound(pos[t].begin(), pos[t].end(), res) - lower_bound(pos[t].begin(), pos[t].end(), sa[i] + ht[i]);
}
printf("%I64d\n", ans);
}
// nantf tai qiang le

CF653F

CF653F Paper task的更多相关文章

  1. [CF653F] Paper task - 后缀数组,线段树,vector

    [CF653F] Paper task Description 给定一个括号序列,统计合法的本质不同子串的个数. Solution 很容易想到,只要在传统统计本质不同子串的基础上修改一下即可. 考虑经 ...

  2. Codeforces 653F Paper task SA

    Paper task 如果不要求本质不同直接st表二分找出最右端, 然后计数就好了. 要求本质不同, 先求个sa, 然后用lcp求本质不同就好啦. #include<bits/stdc++.h& ...

  3. CF IndiaHacks 2016 F Paper task 后缀数组

    题目链接:http://codeforces.com/problemset/problem/653/F 大意是给出一个只包含'('和')'的括号串,求有多少不同的子串是合法的括号串 解法:对于每一个后 ...

  4. Tips for writing a paper

    Tips for writing a paper 1. Tips for Paper Writing 2.• Before you write a paper • When you are writi ...

  5. How to (seriously) read a scientific paper

    How to (seriously) read a scientific paper Adam Ruben’s tongue-in-cheek column about the common diff ...

  6. How to implement an algorithm from a scientific paper

    Author: Emmanuel Goossaert 翻译 This article is a short guide to implementing an algorithm from a scie ...

  7. ### Paper about Event Detection

    Paper about Event Detection. #@author: gr #@date: 2014-03-15 #@email: forgerui@gmail.com 看一些相关的论文. 1 ...

  8. 1090-Rock, Paper, Scissors

    描述 Rock, Paper, Scissors is a classic hand game for two people. Each participant holds out either a ...

  9. Codeforces Round #263 (Div. 1) C. Appleman and a Sheet of Paper 树状数组暴力更新

    C. Appleman and a Sheet of Paper   Appleman has a very big sheet of paper. This sheet has a form of ...

随机推荐

  1. 我的pwn笔记

    0.64位程序参数一次保存在RDI,RSI,RDX,RCX,R8和 R9,具体见图 windows64位调用约定 1.<_libc_csu_init>有一些万能gadget,汇编如下 #! ...

  2. 【原创】Linux基础之sudo

    sudo允许用户以其他用户的身份(比如root)执行命令,比如切换用户.执行命令.读写文件等: 配置 sudo配置在:/etc/sudoers ## Sudoers allows particular ...

  3. 【原创】大数据基础之Oozie(2)使用

    命令行 $ oozie help 1 导出环境变量 $ export OOZIE_URL=http://oozie_server:11000/oozie 否则都需要增加 -oozie 参数,比如 $ ...

  4. hdu4507 数位dp+推公式

    推公式的能力需要锻炼.. /* dp的时候要存结构体 里面三个元素: cnt,就是满足条件的个数 sum1,就是满足条件的数字和 sum2,满足条件的数字平方和 推导过程:还是用记忆化搜索模板 dp[ ...

  5. pta编程总结2

    7-1 币值转换 (20 分) 输入一个整数(位数不超过9位)代表一个人民币值(单位为元),请转换成财务要求的大写中文格式.如23108元,转换后变成"贰万叁仟壹百零捌"元.为了简 ...

  6. Java Spring Boot VS .NetCore (五)MyBatis vs EFCore

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  7. SQL反模式学习笔记21 SQL注入

    目标:编写SQL动态查询,防止SQL注入 通常所说的“SQL动态查询”是指将程序中的变量和基本SQL语句拼接成一个完整的查询语句. 反模式:将未经验证的输入作为代码执行 当向SQL查询的字符串中插入别 ...

  8. Shell 编程详解

    部分引用自:https://blog.csdn.net/qq_22075977/article/details/75209149 一.概述 Shell是一种具备特殊功能的程序,它提供了用户与内核进行交 ...

  9. 2.使用RNN做诗歌生成

    诗歌生成比分类问题要稍微麻烦一些,而且第一次使用RNN做文本方面的问题,还是有很多概念性的东西~~~ 数据下载: 链接:https://pan.baidu.com/s/1uCDup7U5rGuIlIb ...

  10. SpringBoot启动tomcat源码解读

    一.SpringBoot自动拉起Tomcat 原文链接:http://www.studyshare.cn/blog-front/blog/details/1136 SpringBoot框架是当前比较流 ...