HDU4747——2013 ACM/ICPC Asia Regional Hangzhou Online
啦啦啦。
这是杭州网赛的一个题目,当时没做出来,当然这个想法确实比较难想到。
题目质量很高,这个题目也很特别,以前都没做过类似的题目。让我又一次体验了线段树的强大力量。
题目的意思是给你n个数a1-an。对于任何一个区间[l,r],它所对应的值为这个区间内没有出现的最小非负整数,求所有1<=L<=R<=n的区间所对应的值的总和。
比赛的时候苦思无果,以为是什么高端的数据结构或者很奇怪的算法,后来才发现自己坑了。
题目其实是这样的,在最开始预处理所有1开头的(即L=1的所有区间的值,然后从1开始每次都删除一个数,并且更新区间,每次都求一次和,然后就没有然后了,把每次更新后的区间所要求的和加起来就是答案了哦。
这个想法是没有错的,但是实现起来十分的麻烦。我也是经历了若干发TLE,WA,RE以后最终内牛满面地A掉了此题,以此作为纪念。
再讲讲具体是怎么实现的吧!其实预处理的话可以用数组模拟链表来实现,时间非常快(就像建图那种方法),但是由于Ai可能给的很大,所以我们用哈希来实现快速查询啊。记录每个数下一次出现的位置。如果没有出现,那么下一次出现的位置为n+1就好了。
假设当前我已经统计好了Ai作为起点的值,现在要统计Ai+1作为起点的值?应该怎么做?怎么更新呢?
是这样的。找到Ai+1下一次出现的地方的前一位。如果它所对应的那个函数值比当前的小,那说明不用更新了(想想问什么?因为说明有比当前数更小的数没有出现,所以无需更新,而在出现以后的地方显然又已经存在Ai在前面了。)
如果那个数的值大于当前的值,则说明可以修改更新。但是在更新前要先查一下从哪一步开始查找,就二分查找啦,找到第一个大于Ai的数。然后更新区间就可以了。
记得每次删除一个数Ai都要把query(i+1,pos) 的值加到ans里面哦。
总的时间复杂度是:n*log(n)*log(n)。Dangerous !!!
上代码吧:(注意用long long)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#define maxn 200200
#define ll long long
using namespace std; int a[maxn],b[maxn],col[*maxn],next[maxn],cur;
int n,m,k,t,pos;
ll ans,sum[*maxn];
map<int,int> ss;
bool visit[maxn]; void PushDown(int rt,int l,int r)
{
if (col[rt]==-) return;
col[rt<<]=col[rt<<|]=col[rt];
int mid=(l+r)>>;
sum[rt<<]=col[rt]*(mid-l+);
sum[rt<<|]=col[rt]*(r-mid);
col[rt]=-;
} void PushUp(int rt)
{
sum[rt]=sum[rt<<]+sum[rt<<|];
} void build(int rt,int l,int r)
{
col[rt]=-;
if (l==r) { sum[rt]=b[l]; return ; }
int mid=(l+r)>>;
build(rt<<,l,mid);
build(rt<<|,mid+,r);
PushUp(rt);
} void update(int rt,int l,int r,int L,int R,int id)
{
if (L>R) return;
if (L<=l && R>=r)
{
sum[rt]=id*(r-l+);
col[rt]=id;
return ;
}
PushDown(rt,l,r);
int mid=(l+r)>>;
if (L<=mid) update(rt<<,l,mid,L,R,id);
if (R> mid) update(rt<<|,mid+,r,L,R,id);
PushUp(rt);
} ll query(int rt,int l,int r,int L,int R)
{
if (L>R) return ;
if (L<=l && R>=r) return sum[rt];
PushDown(rt,l,r);
int mid=(l+r)>>;
ll tot=;
if (L<=mid) tot=query(rt<<,l,mid,L,R);
if (R> mid) tot+=query(rt<<|,mid+,r,L,R);
return tot;
} int find(int l,int r,int id)
{
int mid;
while (l<r)
{
mid=(l+r)>>;
if (query(,,n,mid,mid)<=id) l=mid+;
else r=mid;
}
return l;
} int main()
{
while (scanf("%d",&n) && (n))
{
ss.clear();
for (int i=; i<=n; i++) scanf("%d",&a[i]);
memset(visit,false,sizeof visit);
for (int i=n; i>=; i--)
{
if (ss[a[i]]!=) next[i]=ss[a[i]];
else next[i]=n+;
ss[a[i]]=i;
}
cur=;
for (int i=; i<=n; i++)
{
if (a[i]<maxn) visit[a[i]]=true;
while (visit[cur]) cur++;
b[i]=cur;
}
build(,,n);
ans=sum[];
for (int i=; i<n; i++)
{
pos=min(next[i]-,n);
if (i+<=pos)
if (query(,,n,pos,pos)>a[i])
{
k=find(i+,pos,a[i]);
update(,,n,k,pos,a[i]);
}
ans+=query(,,n,i+,n);
}
printf("%I64d\n",ans);
}
return ;
}
HDU4747——2013 ACM/ICPC Asia Regional Hangzhou Online的更多相关文章
- hdu 4747 Mex (2013 ACM/ICPC Asia Regional Hangzhou Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 思路: 比赛打得太菜了,不想写....线段树莽一下 实现代码: #include<iost ...
- [2013 ACM/ICPC Asia Regional Hangzhou Online J/1010]hdu 4747 Mex (线段树)
题意: + ;];;;], seg[rt << | ]);)) * fa.setv;) * fa.setv;;], seg[rt << | ], r - l + );;, ...
- 2013 ACM/ICPC Asia Regional Hangzhou Online hdu4739 Zhuge Liang's Mines
Zhuge Liang's Mines Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- HDU4745——Two Rabbits——2013 ACM/ICPC Asia Regional Hangzhou Online
这个题目虽然在比赛的时候苦思无果,但是赛后再做就真的是个水题,赤果果的水题. 题目的意思是给n个数构成的环,两只兔子从任一点开始分别顺逆时针跳,每次可以调到任意一个数(最多不会跳过一圈). 求最多能跳 ...
- HDU 4745 Two Rabbits(最长回文子序列)(2013 ACM/ICPC Asia Regional Hangzhou Online)
Description Long long ago, there lived two rabbits Tom and Jerry in the forest. On a sunny afternoon ...
- HDU 4744 Starloop System(最小费用最大流)(2013 ACM/ICPC Asia Regional Hangzhou Online)
Description At the end of the 200013 th year of the Galaxy era, the war between Carbon-based lives a ...
- HDU 4747 Mex(线段树)(2013 ACM/ICPC Asia Regional Hangzhou Online)
Problem Description Mex is a function on a set of integers, which is universally used for impartial ...
- hduoj 4710 Balls Rearrangement 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4710 Balls Rearrangement Time Limit: 6000/3000 MS (Java/Ot ...
- hduoj 4708 Rotation Lock Puzzle 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4708 Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/O ...
随机推荐
- 20155301 2016-2017-2 《Java程序设计》第8周学习总结
20155301 2016-2017-2 <Java程序设计>第8周学习总结 教材学习内容总结 1.java.util.logging包提供了日志功能相关类与接口.使用日志的起点是logg ...
- 20155338 《Java程序设计》实验三(敏捷开发与XP实践)实验报告
20155338 <Java程序设计>实验三(敏捷开发与XP实践)实验报告 一.实验内容及步骤 (一)使用Code菜单 • 在IDEA中使用工具(Code->Reformate Co ...
- 小程序if else 判断显示隐藏
wxml: <view> <text wx:if="{{ifnumber>80}}">{{ifnumber}}</text> <te ...
- SQL SERVER 无法正常连接的那些事
1.确保sqlserver服务正常运行. >一般可以从两个地方控制服务,一是系统自带的服务管理器,最快捷的方式是运行“services.msc”,二是使用sqlserver自带的“SQL Ser ...
- mysql导入报错【The MySQL server is running with the --event-scheduler=DISABLED】
一.问题: 在进行mysql操作导入库的时候,报出了[The MySQL server is running with the --event-scheduler=DISABLED] 查看后台日志是事 ...
- [POI2011]MET-Meteors
题面 题解 首先我们尝试暴力,那么就对每个点二分一下即可. 我们发现单独二分复杂度太高,而且有些地方很浪费,如求前缀和等. 那么我们就想,能否将它们合并在一起二分呢? 于是就有了整体二分 整体二分即可 ...
- 06004_Redis的启动、使用和停止
1.Redis的启动 (1)前端模式启动 ①直接运行bin/redis-server将以前端模式启动:切换到 /usr/local/redis/bin目录下,然后./redis-server : ②前 ...
- dsp6657的helloworld例程测试-第一篇
环境搭建可以参考http://blog.sina.com.cn/s/blog_ed2e19900102xi2j.html 1. 先从mcsdk导入工程,helloworld例程 2. 提示有错误,估计 ...
- LJ语录
"保持安静,不要打扰我睡觉." ( 半分钟后) "哎呦喂~可以睡觉喽~" "考场上遇到这种题目,你们应该高兴." "因为考场上那群 ...
- ZT-----用javascrip写一个区块链
几乎每个人都听说过像比特币和以太币这样的加密货币,但是只有极少数人懂得隐藏在它们背后的技术.在这篇博客中,我将会用JavaScript来创建一个简单的区块链来演示它们的内部究竟是如何工作的.我将会称之 ...