vijos1760题解
题目:
现在有n个人,题目给出了他们每个人所在市县的编号。他们站在一个从左向右的队伍中。小L不在队列中。他想找到一个长度不超过D的区域,使他能够找到最多的不同地方的朋友。要求输出能找到的朋友所在不同市县的最大数和找到这些朋友的最小区间长度。比如在整个队伍内他按从左向右顺序找到了3个A地朋友,1个B地朋友,1个C地朋友。假设D=5,那么不同市县的最大数为3(A地、B地、C地),最小区间长度为3(只须结交A地的最右面的一个人即可得到最大市县数3,因此区间长度不是5而是3)。假设在队伍内的人他都还没有结交。
在这里写题解时,我总算是长吐了一口气。(因为vijos1000-1653的大部分数据我都有,而此题我没有数据,要是做错了话,是很难修改的)那么,我就把我一步步的想法写下来。
望到100万的数据,肯定是O(n)或是O(log(n)*n)。
后来还有一个最少人数的要求,很明显用最多人数的算法并二分答案。
然而我并不是天才,一开始是怎么也想不到最多人数算法,只是直接想到暴力枚举。(举报:HHD大神在我开始编之前就AK了!!!!)
首先,我想到链表,而且不能用静态数组去代替。范围是n(100万)*k(32768),但实际上数据也就100万个。我本打算一个数组代表一个省份,里面记录该省份的人出现位置,根据同一数组里前后两个数位置进行操作(事实证明仍有点bug)。可是指针我真心不会,看了半天教程,还是云里雾里的。
接着,我想到了之前想法的实际版(链表的不现实,因为我不会)。我们可以把人和位置快排(双关键字),再在每个省份内的人(此时已经连成一块了)里进行操作,同时加一点类似前缀和的优化。以下代码1即是这种实现。
但是,我发现我样例也过不了,为什么呢?我猛然也发现了BUG。突然,我灵光一现,想到了一种真正的算法。由于打字麻烦,在这里引用HHD大神的题解(果然是英雄所见略同!):
先介绍下问题1的解法:
开一个4W的数组,刚开始置为0,表示该地区的大牛当前有几个,然后O(n)模拟。
先处理下1..d有几个不同的地区,然后每次把第一个去掉,然后后一个加上,即改成:2..d+1,然后3..d+2,最后n-d+1...n
每次去掉时,如果去掉后该地区的大牛没了,当前不同地区数就-1,每次加上时,如果加上后该地区大牛只有一个,那么不同地区数+1,每一轮加入删除后更新下答案,这样问题1O(N)搞定
long getans(long d)
{
if(d==0)return 0; long max=0;long now=0;for(longi=1;i<=39999;i++)temp[i]=0; for(long i=1;i<=d;i++) {temp[dl[i]]++;if(temp[dl[i]]==1)max++; }now=max; for(longi=d+1;i<=n;i++) { temp[dl[i-d]]--;if(temp[dl[i-d]]==0)now--;temp[dl[i]]++;if(temp[dl[i]]==1)now++; if(now>max)max=now;
}return max; }
问题2:我们可以发现,如果D越大,那么覆盖的不同地区肯定是严格递增的,而且D<1000000,所以可以二分,然后用上面的getans(d)来检验。时间效率O(nlogn)
但是,当我编好之后交上去,发现WA了两个点!(在代码二中标注)
仔细检查错误,我先把erfen(1,max)改成erfen(0,max),仍无济于事。
后来,我几乎绝望地初始化改成更大的(之前循环到n),没想到A了!
这说明,数据出的很不严谨,明明只有N个人,编号却有N+!
但我也要注意,以后做题时宁可更严谨些。
以下是代码:
代码一:
#include<stdio.h>
using namespace std;
long a[1000001],t,last,ans,ans2,i,max,n;
bool check(long k)
{
long i;
for (i=1;i<=n-k+1;i++)
if (a[i+k-1]-a[i-1]==ans) returntrue;
return false;
}
long erfen(long l,long r)
{
long mid;
mid=(l+r)/2;
if (check(mid)) return erfen(l,mid);
else return erfen(mid+1,r);
}
int main()
{
scanf("%ld %ld",&n,&max);
last=-1;
for (i=1;i<=n;i++)
{
scanf("%ld",&t);
if (t!=last)a[i]=a[i-1]+1;
else a[i]=a[i-1];
last=t;
}
for (i=1;i<=n-max+1;i++)
if (a[i+max-1]-a[i-1]>ans)ans=a[i+max-1]-a[i-1];
printf("%ld ",ans);
ans2=erfen(1,max);
printf("%ld",ans2);
return 0;
}
代码二:
#include<stdio.h>
using namespace std;
longa[1000001],s[32769],t,last,ans,ans2,i,max,n,cnt;
bool check(long k)
{
long i;cnt=0;
for (i=1;i<=32768;i++)s[i]=0;//以前是i<=n
for (i=1;i<=k;i++)
{
s[a[i]]++;if (s[a[i]]==1)cnt++;
}
if (cnt==ans) return true;
for (i=k+1;i<=n;i++)
{
s[a[i]]++;if (s[a[i]]==1)cnt++;
s[a[i-k]]--;if (s[a[i-k]]==0)cnt--;
if (cnt==ans) returntrue;
}
return false;
}
long erfen(long l,long r)
{
long mid;
if (l==r) return l;
mid=(l+r)/2;
if (check(mid)) return erfen(l,mid);
else return erfen(mid+1,r);
}
int main()
{
scanf("%ld %ld",&n,&max);
cnt=0;
for (i=1;i<=n;i++)
{
scanf("%ld",&a[i]);
}
for (i=1;i<=32768;i++)s[i]=0;//以前是i<=n
for (i=1;i<=max;i++)
{
s[a[i]]++;if (s[a[i]]==1)cnt++;
}
if (cnt>ans) ans=cnt;
for (i=max+1;i<=n;i++)
{
s[a[i]]++;if (s[a[i]]==1)cnt++;
s[a[i-max]]--;if (s[a[i-max]]==0)cnt--;
if (cnt>ans)ans=cnt;
}
printf("%ld ",ans);
ans2=erfen(0,max);//以前是(1,max)
printf("%ld",ans2);
//scanf("%ld",&ans);
return 0;
}
vijos1760题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
随机推荐
- 第 9 章 MySQL数据库Schema设计的性能优化
前言: 很多人都认为性能是在通过编写代码(程序代码或者是数据库代码)的过程中优化出来的,其实这是一个非常大的误区.真正影响性能最大的部分是在设计中就已经产生了的,后期的优化很多时候所能够带来的改善都只 ...
- C# 字典 Dictionary
原文地址http://www.cnblogs.com/txw1958/archive/2012/11/07/csharp-dictionary.html 侵删
- 什么是ZigBee、Wifi无线技术?有什么优势?
Zigbee:是基于IEEE802.15.4标准的低功耗个域网协议.根据这个协议规定的技术是一种短距离.低功耗的无线通信技术.这一名称来源于蜜蜂的八字舞,由于蜜蜂(bee)是靠飞翔和"嗡嗡& ...
- 将数据的初始化放到docker中的整个工作过程(问题记录)
将数据的初始化放到docker中的整个工作过程 由于是打算作为个人博客,所以对于install这个步骤,我从一开始就打算删掉的,前面一个多星期一直在修bug,到前天才开始做这个事情. 过程中也是碰到了 ...
- 一天搞定CSS:支持IE的Layout布局--16
1.BFC和Layout区别: BFC和Layout的作用是一样的,只是对浏览器的支持不同而已. BFC- -标准浏览器所具有的 Layout- -IE浏览器所具有的 BFC详解地址:http://b ...
- 抓包工具 - HttpWatch
HttpWatch是功能强大的网页数据分析工具,集成在IE工具栏,主要功能有网页摘要.cookies管理.缓存管理.消息头发送/接收,字符查询.POST数据.目录管理功能和报告输出.HttpWatch ...
- Ajax请求(二)--JQuery的Ajax请求方法
JQuery库的Ajax请求的几种方法: 1. load( url, [data], [callback] ) :载入远程 HTML 文件代码并插入至 DOM 中. 参数含义: url (String ...
- 一张图搞懂容器所有操作 - 每天5分钟玩转 Docker 容器技术(26)
前面我们已经讨论了容器的各种操作,对容器的生命周期有了大致的理解,下面这张状态机很好地总结了容器各种状态之间是如何转换的. 如果掌握了前面的知识,要看懂这张图应该不难.不过有两点还是需要补充一下: 可 ...
- java基础(十二章)
一.变量的作用域(有效的使用范围) 1.变量有2种 1.1成员变量(属性) 声明在类的里面,方法的外面 1.2 局部变量 声明在方法里面或for循环结构中 2.调用时的注意事项(初始值不同.作用域不同 ...
- 放大镜原生js
<!DOCTYPE html><html><head> <title></title> <style type="text/ ...