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语句模拟解 ...
随机推荐
- 在mac上安装rabbitmq
在 OS X 上安装 RabbitMQ¶ 在 Snow Leopard 上安装 RabbitMQ 最简单的方式就是 Homebrew ——OS X 上的一款新颖别致,光彩动人的包管理系统. 在本例中, ...
- 小程序-登录-token
1.前端调用wx.login()获取code值 2.前端通过调用wx.getUserInfo获取iv.rawData.signature.encryptedData等加密数据,传递给后端 3.服务器通 ...
- 密码技术之密钥、随机数、PGP、SSL/TLS
第三部分:密码技术之密钥.随机数.PGP.SSL/TLS 密码的本质就是将较长的消息变成较短的秘密消息——密钥. 一.密钥 什么是密钥? (1)密钥就是一个巨大的数字,然而密钥数字本身的大小不重要,重 ...
- linux运维、架构之路-KVM虚拟化技术
一.云计算概述 云计算:是一种资源使用和交付模式 虚拟化:一种具体的技术,用来将物理机虚拟成为多个相互独立的虚拟机.云计算不等于虚拟化,云计算是使用了虚拟化的技术做支撑 二.KVM配置使用 1.系统环 ...
- tweenMax+如何让数字由初始值动画到结束的值
html: <div class="wz1">0</div> css: .wz1{ width: 114px; height: 30px; position ...
- 开发 .swan 文件
这部分是每个智能小程序页面的展现模板,类似于 Web 开发中的 HTML ,SWAN 模板中使用的标签均为 SWAN 组件规定的标签. <view s-for="item in ite ...
- NPM错误
有时突然报下面错误: 本人经验是IP变了...
- js返回上一页并刷新 代码整理
真正好用: 强制载入后刷新一次 在要载入的页面加入以下代码: <script> if(window.name != "bencalie"){ location.relo ...
- Internet History, Technology, and Security(week5)——Technology: Internets and Packets
前言: 之前都在学习Internet的历史,从这周开始,进入到了Internet技术的学习. Layer1: Link Introduction / The Link Layer 80年代之前,主流网 ...
- es分片shard的数量
适当的提升分片数量可以提升建立索引的速度: 一般情况下:一个索引库建立5-20个分片是最合适的: 注意:如果分片过少或者过多,都会降低检索的速度 分片数过多会导致: 1. 会导致打开比较多的文件2. ...