Codeforces 990C (模拟+组合数学)
题面:
分析:
此题O(n2l)" role="presentation" style="position: relative;">O(n2l)O(n2l)模拟肯定是会超时的(l为所有字符串总长)
我们想到对字符串进行一定的预处理,可以快速计算匹配
我们设每一个(的值为1,)的值为-1,规定
若只有)括号多了x个,则l[i]=r[i]=-x<0
若只有(括号多了x个,则l[i]=r[i]=x>0
那么如何求l[i],r[i]的值呢?
从左到右扫描字符串,用一个变量cnt,统计和
则cnt的最小值=l[i],最终的值=r[i]
若(和)都有多余,则必须接两个字符串,不符合条件,所以计算时应该直接跳过这些字符串,不用考虑
要理解这句话,请看下面的模拟过程
)()
字符串下标(0开始) 0 1 2
cnt值 -1 0 -1
l[i]=-1,说明左边需要一个(括号来匹配 (>=0即不需要)
r[i]=-1,说明右边不需要(<=0即不需要),而左边需要一个(括号
我们以all[i]来hash,哈希表的第 x位存储了所有r[i]=x的字符串的l[i]
但要注意的是,由于负数的原因,数组下标要人为加上一个数addv来存储
为了防止一对字符串被算两次,我们规定字符串只能接在右边,我们枚举字符串时要先保证l[i]>=0才能接,而l[i]<0的只能接在其他字符串右边
对于一个l[i]>=0的字符串i,我们寻找接在它右侧能匹配的字符串,所以我们在哈希表的−r[i]" role="presentation" style="position: relative;">−r[i]−r[i]位置寻找l[i]值为−r[i]" role="presentation" style="position: relative;">−r[i]−r[i]的字符串
比如:()(的l[i]=0,r[i]=1,我们则要寻找r[i]=l[i]=-1,即只多了一个)括号的字符串
用二分查找统计值为−r[i]" role="presentation" style="position: relative;">−r[i]−r[i]的字符串的个数,答案+=值为−r[i]" role="presentation" style="position: relative;">−r[i]−r[i]的字符串的个数
预处理时间复杂度O(l)" role="presentation" style="position: relative;">O(l)O(l) (l为所有字符串总长)
二分查找时间复杂度O(nlog2l)" role="presentation" style="position: relative;">O(nlog2l)O(nlog2l)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define addv 300005
#define maxn 2*addv
using namespace std;
int n;
char str[maxn];
int cnt;
int l[maxn];
int r[maxn];
vector<int>table[maxn];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",str);
int len=strlen(str);
l[i]=maxn;
cnt=0;
for(int j=0;j<len;j++){//像分析中一样求l[i],r[i]
if(str[j]=='(') cnt++;
else cnt--;
l[i]=min(l[i],cnt);
}
r[i]=cnt;
table[r[i]+addv].push_back(l[i]);//hash,为了防止负数人为加上addv,addv就相当于新的零点
}
for(int i=1;i<maxn;i++) if(table[i].size()!=0) sort(table[i].begin(),table[i].end());//排序,为了二分查找
long long ans=0;
for(int i=1;i<=n;i++){
if(l[i]>=0){
int tmp=addv-r[i];//即-r[i]
ans+=table[tmp].end()-lower_bound(table[tmp].begin(),table[tmp].end(),-r[i]);//lower_bound返回第一个>=x的位置,用结尾去-它,可求出l[j]=r[j]=-r[i]的j的个数
}
}
printf("%I64d\n",ans);
}
Codeforces 990C (模拟+组合数学)的更多相关文章
- CodeForces - 427B (模拟题)
Prison Transfer Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Sub ...
- CodeForces - 404B(模拟题)
Marathon Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Submit Sta ...
- Codeforces 709B 模拟
B. Checkpoints time limit per test:1 second memory limit per test:256 megabytes input:standard input ...
- CodeForces - 404A(模拟题)
Valera and X Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Submit ...
- Codeforces 390A( 模拟题)
Inna and Alarm Clock Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64 ...
- Codeforces 452D [模拟][贪心]
题意: 给你k件衣服处理,告诉你洗衣机烘干机折叠机的数量,和它们处理一件衣服的时间,要求一件衣服在洗完之后必须立刻烘干,烘干之后必须立刻折叠,问所需的最小时间. 思路: 1.按照时间模拟 2.若洗完的 ...
- CodeForces - 796B 模拟
思路:模拟移动即可,如果球落入洞中停止移动.注意:有可能第一个位置就是洞!! AC代码 #include <cstdio> #include <cmath> #include ...
- Colorful Bricks CodeForces - 1081C ( 组合数学 或 DP )
On his free time, Chouti likes doing some housework. He has got one new task, paint some bricks in t ...
- CodeForces - 864C-Bus-(模拟加油站问题)
https://vjudge.net/problem/CodeForces-864C 题意:两地之间有个加油站,往返走k个单程,最少加油多少次. 大佬几十行代码就解决,我却要用一百多行的if语句模拟解 ...
随机推荐
- CTF Jarvisoj Web(session.upload_progress.name php 上传进度)
Jarvisoj Web 题目地址:http://web.jarvisoj.com:32784/index.php <?php //A webshell is wait for you ini_ ...
- 配置apache运行cgi程序
配置apache运行cgi程序 文章目录 [隐藏] ScriptAlias目录的CGI ScriptAlias目录以外的CGI 配置apache运行cgi程序可分为两种情况,一是ScriptAlias ...
- os模块 sys模块 json/pickle 模块 logging模块
目录 模块 1. os模块 2. sys模块 3. json和pickle模块 4. logging模块 (1)日志配置 (2)实际开发中日志的使用 模块 1. os模块 os模块有什么用 与操作系统 ...
- day04记
useGeneratedKeys useGeneratedKeys这个只在insert语句中有效,正常情况下useGeneratedKeys默认为false 当useGeneratedKeys为tru ...
- CSS3画五角星和六角星
最终想要实现的效果 一.五角星 在画五角星之前首先分析这个五角星是如何实现,由哪几个部分构成的,示意图如下: 三个顶角向上的三角形,通过设置旋转和定位相互重叠和拼接实现最终的五角星效果. 为了语义化和 ...
- Es6 之 const关键字
https://blog.csdn.net/jin_doudouer/article/details/80493649 es6中新增了一个const.就是用来定义一个常量的.以前其实一直没有把这个放在 ...
- clientX、pageX、offsetX、screenX的区别
这几个属性的区别说难不难,可是很容易搞混,很长一段时间没用,发现又忘记区别了,记不清哪个是哪个!真的很抓狂! 区别: clientX.clientY: 相对于浏览器窗口可视区域的X,Y坐标(窗口坐标) ...
- java 中 进程和线程的区别
目录 什么是进程?什么是线程? 为什么要有线程? 进程与线程的区别? 进程与线程的选择取决条件? 什么是进程?什么是线程?进程:进程是并发执行程序在执行过程中资源分配和管理的基本单位(资源分配的最小单 ...
- vue-cli目录结构介绍
一个vue-cli的项目结构如下: 文件结构细分: 1.build——[webpack配置] build文件主要是webpack的配置,主要启动文件是dev-server.js,当我们输入npm ru ...
- 移动端续讲及zepto移动端插件外加touch插件介绍
媒体查询:针对不同设备,显示不同的样式. 设备像素比:dpr device-piexl-ratio 在he开发中,要一个3陪高清图片: 1080>=320*3 (主要是为了解决图片的失真问题) ...