BZOJ

洛谷


首先旗杆的顺序没有影响,答案之和在某一高度帆的总数有关。所以先把旗杆按高度排序。

设高度为\(i\)的帆有\(s_i\)个,那么答案是\(\sum\frac{s_i(s_i-1)}{2}\),显然我们要让每一行(高度)的帆数都尽量少。

然后可以想到二分,二分每一行的帆数不超过\(mid\)是否可行。显然我们从最高的旗杆的最大高度部分往下填就可以了,要用线段树维护。复杂度\(O(n\log^2n)\)。

但是不需要这个二分啊,每次找到\(s_i\)最小的位置,把\(k\)个帆填进去就行了。

那么显然把旗杆从低到高排序,每次覆盖\(s_i\)最小的区间,就可以保证正确性了。

线段树维护,把这\(k\)个位置填到\([h-k+1,h]\)。这个区间的左端点可能不是一段完整的连续值域区间的左端点,需要将在该一部分平移到该连续段左端点去覆盖来保证\(s_i\)递减。对此就找到\(h-k+1\)位置处连续段的左右端点\(L,R\),判一下\(R\)是否\(<h\)就好了。(画个图很容易理解,初始时就可能是这样的)

复杂度\(O(n\log n)\)。


可以用树状数组写,虽然查询位置是两个\(\log\)的,但是常数太小了没O2线段树比不过。

//5028kb	1036ms
#include <cstdio>
#include <cctype>
#include <algorithm>
#define mp std::make_pair
#define pr std::pair<int,int>
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+5; pr A[N];
char IN[MAXIN],*SS=IN,*TT=IN;
struct Segment_Tree
{
#define ls rt<<1
#define rs rt<<1|1
#define lson l,m,ls
#define rson m+1,r,rs
#define S N<<2
int mn[S],tag[S];
#undef S
#define Upd(rt,v) mn[rt]+=v,tag[rt]+=v
#define Update(rt) mn[rt]=std::min(mn[ls],mn[rs])
#define PushDown(rt) Upd(ls,tag[rt]), Upd(rs,tag[rt]), tag[rt]=0
void Modify(int l,int r,int rt,int L,int R)
{
if(L<=l && r<=R) {Upd(rt,1); return;}
if(tag[rt]) PushDown(rt);
int m=l+r>>1;
if(L<=m) Modify(lson,L,R);
if(m<R) Modify(rson,L,R);
Update(rt);
}
int FindPos(int l,int r,int rt,int p)
{
while(l!=r)
{
if(tag[rt]) PushDown(rt);
int m=l+r>>1;
p<=m ? (r=m,rt=ls) : (l=m+1,rt=rs);
}
return mn[rt];
}
int FindL(int l,int r,int rt,int val)
{
while(l!=r)
{
if(tag[rt]) PushDown(rt);
int m=l+r>>1;
mn[ls]<=val ? (r=m,rt=ls) : (l=m+1,rt=rs);
}
return l;
}
int FindR(int l,int r,int rt,int val)
{
while(l!=r)
{
if(tag[rt]) PushDown(rt);
int m=l+r>>1;
mn[ls]<val ? (r=m,rt=ls) : (l=m+1,rt=rs);
}
return mn[rt]==val?l:l-1;
}
LL Calc(int l,int r,int rt)
{
if(l==r) return 1ll*mn[rt]*(mn[rt]-1)>>1;
if(tag[rt]) PushDown(rt);
int m=l+r>>1;
return Calc(lson)+Calc(rson);
}
}T; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
} int main()
{
#define S 1,lim,1
const int n=read();
for(int i=1,h; i<=n; ++i) h=read(),A[i]=std::make_pair(h,read());//h,k
std::sort(A+1,A+1+n);
int lim=A[n].first;
for(int i=1; i<=n; ++i)
{
int h=A[i].first,k=A[i].second;
int mn=T.FindPos(S,h-k+1),L=T.FindL(S,mn),R=std::min(h,T.FindR(S,mn));
if(L!=h-k+1)//if(R<h)
{
T.Modify(S,L,L+k-h+R-1);
if(R<h) T.Modify(S,R+1,h);
}
else T.Modify(S,L,L+k-1);
}
printf("%lld\n",T.Calc(S)); return 0;
}

BZOJ.1805.[IOI2007]sail船帆(贪心 线段树)的更多相关文章

  1. BZOJ4391 High Card Low Card [Usaco2015 dec](贪心+线段树/set库

    正解:贪心+线段树/set库 解题报告: 算辣直接甩链接qwq 恩这题就贪心?从前往后从后往前各推一次然后找一遍哪个地方最大就欧克了,正确性很容易证明 (这里有个,很妙的想法,就是,从后往前推从前往后 ...

  2. 【题解】P1712 [NOI2016]区间(贪心+线段树)

    [题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...

  3. BZOJ1805[Ioi2007]Sail船帆——线段树+贪心

    题目描述 让我们来建造一艘新的海盗船.船上有 N个旗杆,每根旗杆被分成单位长度的小节.旗杆的长度等于它被分成的小节的数目.每根旗杆上会挂一些帆,每张帆正好占据旗杆上的一个小节.在一根旗杆上的帆可以任意 ...

  4. BZOJ.5249.[九省联考2018]iiidx(贪心 线段树)

    BZOJ LOJ 洛谷 \(d_i\)不同就不用说了,建出树来\(DFS\)一遍. 对于\(d_i\)不同的情况: Solution 1: xxy tql! 考虑如何把这些数依次填到树里. 首先对于已 ...

  5. BZOJ 5249: [2018多省省队联测]IIIDX(贪心 + 线段树)

    题意 这一天,\(\mathrm{Konano}\) 接到了一个任务,他需要给正在制作中的游戏 \(\mathrm{<IIIDX>}\) 安排曲目 的解锁顺序.游戏内共有\(n\) 首曲目 ...

  6. bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle【贪心+线段树】

    按结束时间排序,然后开个线段树,按照排序后的牛群贪心的选 贪心的依据是选哪头牛都是选,不如给后面的多省一点空间 #include<iostream> #include<cstdio& ...

  7. bzoj 1828: [Usaco2010 Mar]balloc 农场分配【贪心+线段树】

    长得挺唬人的贪心,按照右端点排序,用最小值线段树的询问判断当前牛是否能放进去,能的话更新线段树,ans++ 来自https://www.cnblogs.com/rausen/p/4529245.htm ...

  8. BZOJ 1828 [Usaco2010 Mar]balloc 农场分配(贪心+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1828 [题目大意] 现在有一些线段[l,r]的需求需要满足,i位置最多允许a[i]条线 ...

  9. Codeforces 675E Trains and Statistic(DP + 贪心 + 线段树)

    题目大概说有n(<=10W)个车站,每个车站i卖到车站i+1...a[i]的票,p[i][j]表示从车站i到车站j所需买的最少车票数,求所有的p[i][j](i<j)的和. 好难,不会写. ...

随机推荐

  1. Java中Super和final关键字以及异常类

    1.final类不能有子类,也就谈不上继承的说法,如果用final修饰成员变量或者局部变量,那成了常量需要制定常量的值. 2.对象的上转型对象,上转型对象不能操作子类新增的成员变量,不能调用子类新增的 ...

  2. HTML&javaSkcript&CSS&jQuery&ajax-Css

    CSS 1 .eg <head> <style> body{ background-color:#d0e4fe;} h1{ color:orange; text-alin:ce ...

  3. python 自动获取手机短信验证码

    需要一个有权限的 APK 在手机实时存储短信到手机内存 /sdcard/smslog.txt 里(外部SD卡也可以知道能通过adb命令访问到): /***** ...... try {long tim ...

  4. 图像特征的提取(gaussian,gabor,frangi,hessian,Morphology...)及将图片保存为txt文件

    # -*- coding: utf-8 -*- #2018-2-19 14:30:30#Author:Fourmi_gsj import cv2 import numpy as np import p ...

  5. azkaban group分组,权限

    翻译自:https://azkaban.readthedocs.io/en/latest/userManager.html?highlight=group 1.job project,名为" ...

  6. 005-Python字典

    Python字典(dict) 字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号{}中: ...

  7. ArcGIS 卷帘效果

    一直没注意ArcGIS自带了卷帘功能,使用方法:调出Effects工具条,里面就有卷帘工具. AE开发参考: http://bbs.esrichina-bj.cn/esri/viewthread.ph ...

  8. net core体系-web应用程序-4asp.net core2.0 项目实战(1)-7项目缓冲方案( Redis)

    本文目录1. 摘要2. Redis配置3. RedisHelper4.使用实例 5. 总结 1.  摘要 由于內存存取速度远高于磁盘读取的特性,为了程序效率提高性能,通常会把常用的不常变动的数据存储在 ...

  9. Codeforces 1139E Maximize Mex 二分图匹配

    Maximize Mex 离线之后把删数变成加数, 然后一边跑匈牙利一遍算答案. #include<bits/stdc++.h> #define LL long long #define ...

  10. JavaScript 组数去重demo

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...