啦啦啦。

这是杭州网赛的一个题目,当时没做出来,当然这个想法确实比较难想到。

题目质量很高,这个题目也很特别,以前都没做过类似的题目。让我又一次体验了线段树的强大力量。

题目的意思是给你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的更多相关文章

  1. hdu 4747 Mex (2013 ACM/ICPC Asia Regional Hangzhou Online)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 思路: 比赛打得太菜了,不想写....线段树莽一下 实现代码: #include<iost ...

  2. [2013 ACM/ICPC Asia Regional Hangzhou Online J/1010]hdu 4747 Mex (线段树)

    题意: + ;];;;], seg[rt <<  | ]);)) * fa.setv;) * fa.setv;;], seg[rt <<  | ], r - l + );;,  ...

  3. 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 ...

  4. HDU4745——Two Rabbits——2013 ACM/ICPC Asia Regional Hangzhou Online

    这个题目虽然在比赛的时候苦思无果,但是赛后再做就真的是个水题,赤果果的水题. 题目的意思是给n个数构成的环,两只兔子从任一点开始分别顺逆时针跳,每次可以调到任意一个数(最多不会跳过一圈). 求最多能跳 ...

  5. 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 ...

  6. 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 ...

  7. 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 ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. 20155230 《Java程序设计》实验五 Java网络编程及安全

    20155230 <Java程序设计>实验五 Java网络编程及安全 实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全传输系统. 实验1 两人一组结对编程 ...

  2. 20155307 实验四 Android程序设计

    在安装as的过程中一路顺风,一点问题都没有,但是在编译的时候总是出现错误,无论是我用自己的手机还是虚拟的手机都不能成功. 但是我上网百度,发现错误原因为compileSdkVersion的版本出了问题 ...

  3. js获取上月的最后一天

    一.问题: 在最近的开发中遇到一个需求,需要初始化默认时间为上月的最后一天 而在日历中这个值在每个月都不是固定的 二.分析: 问题可以转化为,获取指定月份时间的月末最后一天,下边是代码,供大家参考 f ...

  4. easyui树动态加载参考

    这篇文章是拷贝的,多谢原作者 友情连接:http://www.jb51.net/article/28771.htm var treeTitle = '选择列表'; var treeUrl = '../ ...

  5. Python中的对象引用、浅拷贝与深拷贝

    最近项目中遇到一个Python浅拷贝机制引起的bug,由于对于Python中对象引用.赋值.浅拷贝/深拷贝机制没有足够的认识,导致调试了很久才发现问题,这里简单记录一下相关概念. 在Python的设计 ...

  6. 成都Uber优步司机奖励政策(4月13日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  7. 1178: [Apio2009]CONVENTION会议中心

    1178: [Apio2009]CONVENTION会议中心 https://lydsy.com/JudgeOnline/problem.php?id=1178 分析: set+倍增. 首先把所有有包 ...

  8. Pomelo.AspNetCore.TimedJob 允许依赖注入

    public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStar ...

  9. 【JUC源码解析】ConcurrentSkipListMap

    简介 基于跳表,支持并发,有序的哈希表. 跳表 红色路径为寻找结点F. 拿空间换时间,时间复杂度,O(nlogn). 源码分析 内部类 Node 属性 final K key; // 键 volati ...

  10. stl源码分析之list

    本文主要分析gcc4.8版本的stl list的源码实现,与vector的线性空间结构不同,list的节点是任意分散的,节点之间通过指针连接,好处是在任何位置插入删除元素都只需要常数时间,缺点是不能随 ...