HUAS 2017暑假第六周比赛-题解
A.Parenthesis
括号匹配的问题有一种经典的做法。
将左括号看成1,右括号看成-1,做一遍前缀和sum。
括号序列是合法的当且仅当\(sum[n]=Min(sum[1],sum[2]....sum[n])=0\)时成立。
于是问题变成了交换两个括号后如何维护sum数组的值。
实际上交换a和b之后只会影响到\((sum[a],sum[a+1]....sum[b-1])\)。
1.\(s[a]=(,s[b]=)\) 对应的区间减2。
2.\(s[a]=),s[b]=(\) 对应的区间加2。
我们只需要维护一个支持区间查询最小值,区间加减的数据结构即可。
显然线段树可以完成这些操作。时间复杂度\(O(qlogn)\)
# include <bits/stdc++.h>
using namespace std;
const int N=100005;
int sum[N], seg[N<<3], tag[N<<3];
char s[N];
void push_up(int p){seg[p]=min(seg[p<<1],seg[p<<1|1]);}
void push_down(int p){
if (!tag[p]) return ;
seg[p]+=tag[p]; tag[p<<1]+=tag[p]; tag[p<<1|1]+=tag[p]; tag[p]=0;
}
void init(int p, int l, int r){
if (l<r) {
int mid=(l+r)>>1;
init(p<<1,l,mid); init(p<<1|1,mid+1,r); push_up(p);
}
else seg[p]=sum[l], tag[p]=0;
}
void update(int p, int l, int r, int L, int R, int val){
push_down(p);
if (L>r||R<l) return ;
if (L<=l&&R>=r) tag[p]+=val, push_down(p);
else {
int mid=(l+r)>>1;
update(p<<1,l,mid,L,R,val); update(p<<1|1,mid+1,r,L,R,val); push_up(p);
}
}
int main ()
{
int n, q, l, r;
while (~scanf("%d%d",&n,&q)) {
scanf("%s",s+1);
for (int i=1; i<=n; ++i) sum[i]=sum[i-1]+(s[i]=='('?1:-1);
init(1,1,n);
while (q--) {
scanf("%d%d",&l,&r);
if (l>r) swap(l,r);
if (s[l]!=s[r]) {
if (s[l]=='(') update(1,1,n,l,r-1,-2);
else update(1,1,n,l,r-1,2);
}
puts(seg[1]==0?"Yes":"No");
if (s[l]!=s[r]) {
if (s[l]=='(') update(1,1,n,l,r-1,2);
else update(1,1,n,l,r-1,-2);
}
}
}
return 0;
}
B.权势二进制
题目可以换一种描述。
给出n,问至少可以表示为多少个数位上面只有0和1的数字之和。
显然答案即为n的十进制数位的最大值,即\(max(n\%10,n\%100,n\%1000....)\)
时间复杂度\(O(logn)\)。
# include <bits/stdc++.h>
using namespace std;
char s[10];
int main ()
{
int ans=0;
scanf("%s",s);
for (int i=0; s[i]; ++i) ans=max(ans,s[i]-'0');
printf("%d\n",ans);
return 0;
}
C.天气晴朗的魔法
如果不考虑边权的最大值最小的话,答案就是最大生成树。
现在要求图的生成树中边权的最大值最小。
实际上由Kruskal的算法流程可知,这个值就是图的最小生成树的最大边,不可能比这更小了。
因此,先对图求一遍最小生成树,获得这个最大值,然后把小于等于这个最大值的边
拉出来再求一遍最大生成树,显然即为答案。
时间复杂度\(O(mlogm)\)。
# include <bits/stdc++.h>
using namespace std;
const int N=200005;
struct Edge{int u, v, w;}edge[N];
int n, m, F[N];
long long ans=0;
int find(int x){return F[x]==0?x:F[x]=find(F[x]);}
bool comp(Edge a, Edge b){return a.w<b.w;}
void Kruskal(){
sort(edge+1,edge+m+1,comp);
int Max_w;
for (int i=1; i<=m; ++i) {
int u=find(edge[i].u), v=find(edge[i].v);
if (u==v) continue;
F[u]=v; Max_w=edge[i].w;
}
memset(F,0,sizeof(F));
for (int i=m; i>=1; --i) {
if (edge[i].w>Max_w) continue;
int u=find(edge[i].u), v=find(edge[i].v);
if (u==v) continue;
F[u]=v; ans+=edge[i].w;
}
}
int main ()
{
scanf("%d%d",&n,&m);
for (int i=1; i<=m; ++i) scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
Kruskal();
printf("%lld\n",ans);
return 0;
}
D.大鱼吃小鱼
用栈来进行模拟,向右边走的鱼入栈,左边走的鱼和栈顶的鱼进行比较,
如果左边走的鱼比栈顶的鱼体积小,那么就会被吃掉。
否则吃掉栈顶的鱼继续和栈顶的下一个鱼进行比较,直到被吃掉或者栈为空为止。
模拟过程中一共多少鱼会被吃掉,最后拿总数减去它即可答案。
时间复杂度\(O(n)\)。
# include <bits/stdc++.h>
using namespace std;
const int N=100005;
int st[N], top=0;
int main ()
{
int n, a, b, sum=0;
scanf("%d",&n);
for (int i=1; i<=n; ++i) {
scanf("%d%d",&a,&b);
if (b==1) st[++top]=a;
else {
while (top&&st[top]<a) --top, ++sum;
if (top) ++sum;
}
}
printf("%d\n",n-sum);
return 0;
}
E.0和1相等串
将0写成-1,对原序列做一遍前缀和sum。
那么区间\([l,r]\)的0和1出现次数相等的充分必要条件为\(sum[r]=sum[l-1]\)。
现在要找到最大的\(r-l+1\)使得\(sum[r]=sum[l-1]\)。
我们扫一遍sum数组,记录每个val对应的\(sum[i]=val\)的下标i的最大值\(i_{max}\)和最小值\(i_{min}\)。那么这个val对应的答案就是\(i_{max}-i_{min}\)。
对所有val的答案取最大值即可。
时间复杂度\(O(len)\)
# include <bits/stdc++.h>
using namespace std;
const int N=1000005;
int sum[N], Min_p[N<<1], Max_p[N<<1];
char s[N];
const int P=1000000;
int main ()
{
scanf("%s",s+1);
int n=strlen(s+1);
memset(Min_p,-1,sizeof(Min_p)); memset(Max_p,-1,sizeof(Max_p));
for (int i=1; i<=n; ++i) sum[i]=sum[i-1]+(s[i]=='1'?1:-1);
for (int i=0; i<=n; ++i) {
int x=sum[i];
if (Min_p[x+P]==-1) Min_p[x+P]=i;
}
for (int i=n; i>=0; --i) {
int x=sum[i];
if (Max_p[x+P]==-1) Max_p[x+P]=i;
}
int ans=0;
for (int i=0; i<=n+P; ++i) if (Min_p[i]!=-1) ans=max(ans,Max_p[i]-Min_p[i]);
printf("%d\n",ans);
return 0;
}
F.部落划分
如果我们已经确定了最优划分时,最近的两个部落的距离为d,那么我们至多可以将野人划分为几个部落呢?
我们可以推出,如果两个野人之间的距离<d,那么它们必然是一个部落的。
那么我们可以\(O(n^2)\)枚举两个野人,将相同部落的野人的用并查集合并,最后可以得到野人至多被划分为几个部落。
现在的问题是,我们还无法知道答案d应该为多少。
幸运的是,令划分后的部落数\(y=f(d)\),这个函数是单调递减的。
于是我们可以二分d,来找到最大的d,使得\(f(d)=K\)。此时即为答案。
时间复杂度\(O(n^2log(maxdis))\)。
# include <bits/stdc++.h>
using namespace std;
const int N=100005;
int a[N][2], f[N], n, k, F[N];
int find(int x){return F[x]==0?x:F[x]=find(F[x]);}
bool check(double x){
int res=n, u, v;
x=x*x;
memset(F,0,sizeof(F));
for (int i=1; i<=n; ++i) for (int j=i+1; j<=n; ++j) {
if ((a[i][0]-a[j][0])*(a[i][0]-a[j][0])+(a[i][1]-a[j][1])*(a[i][1]-a[j][1])>=x) continue;
u=find(i), v=find(j);
if (u!=v) F[u]=v, --res;
}
return res>=k;
}
int main ()
{
scanf("%d%d",&n,&k);
for (int i=1; i<=n; ++i) scanf("%d%d",&a[i][0],&a[i][1]);
double l=0, r=20000, mid;
for (int i=1; i<=50; ++i) {
mid=(l+r)/2;
if (check(mid)) l=mid;
else r=mid;
}
printf("%.2f\n",mid);
return 0;
}
G.2016
\((a\times b)\%2016=0\Rightarrow ((a\%2016)\times (b\%2016))\%2016=0\)
\(x=a\%2016,y=b\%2016\Rightarrow 0<=x<2016,0<=y<2016\)
预处理出满足条件的\((x,y)\),对于每个这样的\((x,y)\)求出对应的\((a,b)\)有多少种即可。
显然应为\(\frac{n-x}{2016}\times \frac{m-y}{2016}\)。另外注意对x=0和y=0情况的特殊处理即可。
时间复杂度\(O(2016\times 2016)\)。
# include <bits/stdc++.h>
using namespace std;
const int N=2015;
struct Node{int x, y;}node[N*N];
int pos;
void init(){
for (int i=0; i<=2015; ++i) for (int j=0; j<=2015; ++j) {
if (i*j%2016) continue;
node[++pos].x=i; node[pos].y=j;
}
}
int main ()
{
init();
int n, m;
long long ans;
while (~scanf("%d%d",&n,&m)) {
ans=0;
for (int i=1; i<=pos; ++i) {
if (node[i].x>n || node[i].y>m) continue;
ans+=(long long)((n-node[i].x)/2016+(node[i].x?1:0))*((m-node[i].y)/2016+(node[i].y?1:0));
}
printf("%lld\n",ans);
}
return 0;
}
HUAS 2017暑假第六周比赛-题解的更多相关文章
- HUAS 2018暑假第一周比赛-题解
小朋友们有问题评论区 :) B. 子串计算 难度系数 : ☆ Main idea : 模拟 暴力 按照题目的要求一步一步来就行了 之所以可行的原因是从左往右扫,如果扫到一个子串,把它删除掉之后,假设当 ...
- CodeForces 569A 第六周比赛C踢
C - C Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Submit Statu ...
- CodeForces 478B 第六周比赛B题
B - B Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Descriptio ...
- LightOJ 1317 第六周比赛A题
A - A Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Description Y ...
- 暑假集训第一周比赛C题
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83146#problem/C C - 学 Crawling in process... C ...
- 暑假集训第一周比赛G题
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83146#problem/G G - 向 Crawling in process... C ...
- 暑假第六周总结(对HBASE进行编程实践并且安装Redis)
本周主要是根据教程对HBASE进行了编程实践,对于hadoop的编程来说需要用到很多的.jar 包,在进行编程实践的时候需要参照相关的教程将jar包添加至程序当中去.教程上给的代码还是比较详细的,加上 ...
- 大二暑假第六周总结--开始学习Hadoop基础(五)
简单学习数据仓库HIVE HIVE是一个构建于Hadoop顶端的数据仓库工具 支持大规模数据存储,分析,具有良好的可扩展性 某种程度上可以看做是用户编程接口,本身不存储和处理数据 依赖分布式系统HDF ...
- 第六周学习总结-CSS、JavaScript
2018年8月19日 这是暑假第六周,这一周我把HTML5的标签大致看完了,并且看了一些CSS和JavaScript的内容. 上一周说这周要把那个简陋的网页用CSS修饰一下,但是真正开始做时,才发现C ...
随机推荐
- 数据结构与算法 —— 链表linked list(06)
回文链表 链接 请检查一个链表是否为回文链表. 进阶:你能在 O(n) 的时间和 O(1) 的额外空间中做到吗? 解题思路: 回文链表的特点就是对称. 把链表放到栈中去,利用栈的先进后出的规则,和原链 ...
- 使用web api开发微信公众号,调用图灵机器人接口(二)
此文将分两篇讲解,主要分为以下几步 签名校验; 首次提交验证申请; 接收消息; 被动响应消息(返回XML); 映射图灵消息及微信消息; 此篇为第二篇. 被动响应消息(返回XML) 上一篇中,我们已经可 ...
- centos下安装docker,kubelet kubeadm kubectl
目录 安装docker 安装命令 安装 kubelet kubeadm kubectl 安装命令 安装docker 安装命令 yum install docker -y 启动 systemctl en ...
- Java+Netty实现的RESTful框架--netty-rest-server
在工作中用Netty做了几个服务,感觉Netty做出来的程序性能好,资源占用少,但是实现Http服务比较麻烦,于是就参考Spring MVC的注解基于Netty实现了一个轻量级的RESTful框架. ...
- 报错:Cannot create PoolableConnectionFactory (The server time zone value 'CST' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverT
报错:Cannot create PoolableConnectionFactory (The server time zone value 'CST' is unrecognized or repr ...
- Spring集成Kafka-注解,xml配置2种方式实现
准备工作: 1.安装kafka+zookeeper环境 2.利用命令创建好topic 参考官网 http://kafka.apache.org/documentation/ 一XML配置文件方式实现
- 关于matlab向文件写入数据的方法——留着备用
MATLAB数据采集的时候,往往需要把得到的数据保存下来. fid = fopen(文件名,‘打开方式’): 说明:fid用于存储文件句柄值,如果fid>0,这说明文件打开成功.打开方式有如下选 ...
- 记一次开发人员的奇葩操作-------导致root用户不能登录
首先,我表示国庆长假被开发呼叫,是一件很不开心的事...... 1.问开发,是不是/etc/passwd文件被更改了? 回答:没有 还好是新装的服务器,还好哥有服务器管理口的远程控制 单用户模式 ...
- Windows下用HackRF和SDR#收听FM
本文内容.开发板及配件仅限用于学校或科研院所开展科研实验! 淘宝店铺名称:开源SDR实验室 HackRF链接:https://item.taobao.com/item.htm?spm=a1z10.1- ...
- AJAX请求中出现OPTIONS请求
背景 有一个前后端分离的VUE项目来发送ajax请求, 查看Nginx日志或使用Chrome Dev Tools查看请求发送情况时, 会看到每次调后台API的请求之前, 都会发送一个OPTIONS请求 ...