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语句模拟解 ... 
随机推荐
- 前端每日实战:14# 视频演示如何用纯 CSS 创作一种侧立图书的特效
			效果预览 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/pen/deVgRM 可交互视频教程 此视频是可以交 ... 
- 模块打包 webpack
			1.模块打包工具 2.工作方式: 1)将存在依赖关系的模块按照特定规则合并为单个JS文件,一次全部加载进页面中 2)在页面初始时加载一个入口模块,其他模块异步的进行加载 3.优势: 1)支持AMD,C ... 
- 前端之JQuery:JQuery基本语法
			jQuery基本语法 一.jQuery基础1.为什么要用jquery? 写起来简单,省事,开发效率高,兼容性好2.什么是jQuery? jQuery是一个兼容多浏览器的JavaScript库(类似py ... 
- ARC模式下delloc()注意事项
			1.ARC模式下delloc()调用触发时机是对象被销毁,如self.属性=nil 2.ARC模式下delloc()里面不需要手动调用[super dealloc]; 因为系统已经自动调用,多此一举的 ... 
- jq刷新页面
			//页面加载时绑定按钮点击事件$(function(){ $("#按钮id").click(function(){ refresh(); });});// ... 
- (42)嵌入式项目中常用到的C语言技能总结
			嵌入式项目中常用到的C语言技能 1.指针 .结构体. 枚举. 联合.数组.字符串.链表七个专题 2.结构体指针.结构体的多重嵌套[结构体中嵌套结构体.结构体中嵌套枚举.联合体.结构体中嵌套函数指针.一 ... 
- React-Native 之 GD (十七)小时风云榜按钮处理
			小时风云榜按钮处理 在服务器返回给我们的 json 数据中,提供了 hasnexthour 字段,当这个字段返回为 1 的时候,表示后面还有内容,按钮可以点击,否则不能点击,按照这个思路,我们就来完成 ... 
- Linux 下wdcp支持两种安装方式
			wdcp支持两种安装方式1 源码编译 此安装比较麻烦和耗时,一般是20分钟至一个小时不等,具体视机器配置情况而定2 RPM包安装 简单快速,下载快的话,几分钟就可以完成源码安装(ssh登录服务器,执行 ... 
- Redis 简介,安装,卸载
			一.Redis简介 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(s ... 
- 【tensorflow使用笔记二】:tensorflow中input_data.py代码有问题的解决方法
			由于input_data网页打不开,因此从博客找到代码copy: https://blog.csdn.net/weixin_43159628/article/details/83241345 将代码放 ... 
