思路:我们考虑如果取掉一个部分,那么能影响到最优解的只有离它最近的那两个部分。

因此我们考虑堆维护最小的部分,离散化离散掉区间,然后用线段树维护区间有没有雪,最后用平衡树在线段的左右端点上面维护最小的id

我讲的貌似不是很清楚。。

还有,蜜汁80分,打死也改不出来。。

 #include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
struct node{
int l,r,cnt,id;
}a[];
struct segment{
int l,r,v;
segment(){}
segment(int l0,int r0,int v0):l(l0),r(r0),v(v0){}
}t[];
struct treap{
int l,r,rnd,v;
}tt[];
int tag[],vis[],Tcase;
int len[],next[],before[],pos[],heap[];
int o[],p[],sz,Id[],pls[];
int c[],Cnt,sb,rt1[],rt2[],all[];
int tot,n,Len;
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
bool cmp(node a,node b){
return a.r-a.l<b.r-b.l;
}
void push_up(int x){
while (x>){
if (len[x/]>len[x]||(len[x/]==len[x]&&heap[x/]>heap[x])) std::swap(len[x/],len[x]),std::swap(heap[x/],heap[x]),std::swap(pos[heap[x]],pos[heap[x/]]);
else break;
x/=;
}
}
void push_down(int x){
int j;
while (x*<=tot){
if (x*==tot) j=*x;
else if (len[*x]<len[*x+]||(len[*x]==len[*x+]&&heap[*x]<heap[*x+])) j=*x;
else j=*x+;
if (len[x]>len[j]||(len[x]==len[j]&&heap[j]<heap[x])){
std::swap(len[x],len[j]);
std::swap(heap[x],heap[j]);
std::swap(pos[heap[x]],pos[heap[j]]);
}
x=j;
}
}
void add_heap(int x,int v){
heap[++tot]=x;
len[tot]=v;
pos[x]=tot;
push_up(tot);
}
void delete_heap(int x){
int Pos=pos[x];
heap[Pos]=heap[tot];
len[Pos]=len[tot];
pos[heap[tot]]=Pos;
tot--;
push_down(Pos);
}
void modify_heap(int x,int y){
int Pos=pos[x];
len[Pos]=y;
push_up(Pos);
}
void build(int k,int l,int r){
if (l==r){
t[k].v=o[l];
t[k].l=t[k].r=l;
return;
}
int mid=(l+r)>>;
build(k*,l,mid);
build(k*+,mid+,r);
t[k].v=t[k*].v+t[k*+].v;
t[k].l=std::min(t[k*].l,t[k*+].l);
t[k].r=std::max(t[k*].r,t[k*+].r);
}
void pushdown(int k,int l,int r){
if (!tag[k]||l==r) return;
tag[k]=;
t[k*].v=t[k*+].v=;
tag[k*]=tag[k*+]=;
t[k*].l=t[k*+].l=Len+;
t[k*].r=t[k*+].r=;
}
void modify(int k,int l,int r,int x,int y){
if (l>r) return;
if (l>y||r<x) return;
pushdown(k,l,r);
if (l==x&&r==y){
tag[k]=;
t[k].l=Len+;
t[k].r=;
t[k].v=;
pushdown(k,l,r);
return;
}
int mid=(l+r)>>;
if (y<=mid) modify(k*,l,mid,x,y);
else
if (x>mid) modify(k*+,mid+,r,x,y);
else modify(k*,l,mid,x,mid),modify(k*+,mid+,r,mid+,y);
t[k].v=t[k*].v+t[k*+].v;
t[k].l=std::min(t[k*].l,t[k*+].l);
t[k].r=std::max(t[k*].r,t[k*+].r);
}
segment query(int k,int l,int r,int x,int y){
if (x>y) return segment(x,y,);
pushdown(k,l,r);
if (l==x&&r==y){
return segment(t[k].l,t[k].r,t[k].v);
}
int mid=(l+r)>>;
if (y<=mid) return query(k*,l,mid,x,y);
else
if (x>mid) return query(k*+,mid+,r,x,y);
else{
segment t1=query(k*,l,mid,x,mid);
segment t2=query(k*+,mid+,r,mid+,y);
return segment(std::min(t1.l,t2.l),std::max(t1.r,t2.r),t1.v+t2.v);
}
}
int find(int x){
int l=,r=p[];
while (l<=r){
int mid=(l+r)>>;
if (p[mid]==x) return Id[mid];
if (p[mid]<x) l=mid+;
else r=mid-;
}
}
void sbpianfen1(){
int T=n;
for (int i=;i<=n;i++)
a[i].l=read(),a[i].r=read(),a[i].id=i,a[i].cnt=a[i].r-a[i].l+,add_heap(i,a[i].r-a[i].l+),p[++p[]]=a[i].l,p[++p[]]=a[i].r;
std::sort(p+,p++p[]);int j=;
for (int i=;i<=p[];i++)
if (p[i]!=p[j]) p[++j]=p[i];p[]=j; for (int i=;i<=p[];i++)
if (p[i]!=p[i-]){
o[++sz]=p[i]-p[i-]-;
o[++sz]=;
Id[i]=sz;
}
Len=sz;
for (int i=;i<=n;i++)
a[i].l=find(a[i].l),a[i].r=find(a[i].r);
build(,,Len);
a[n+].cnt=0x7fffffff;
while (T--){
int mn=n+;
for (int i=n;i>=;i--)
if (a[i].cnt<=a[mn].cnt&&!vis[i]) mn=i;
printf("%d\n",mn);vis[mn]=;
modify(,,Len,a[mn].l,a[mn].r);
for (int i=;i<=n;i++){
segment t1=query(,,Len,a[i].l,a[i].r);
a[i].cnt=t1.v;
}
}
}
void lturn(int &k){
if (!k) return;
int TT=tt[k].r;tt[k].r=tt[TT].l;tt[TT].l=k;k=TT;
}
void rturn(int &k){
if (!k) return;
int TT=tt[k].l;tt[k].l=tt[TT].r;tt[TT].r=k;k=TT;
}
void insert(int &k,int v){
if (!k){
if (Cnt) k=c[Cnt--];else k=++sb;
tt[k].l=tt[k].r=;tt[k].rnd=rand();
tt[k].v=v;
all[v]++;
return;
}
if (tt[k].v==v) {all[v]++;return;}
if (tt[k].v<v){
insert(tt[k].r,v);
if (tt[tt[k].r].rnd<tt[k].rnd) lturn(k);
}else{
insert(tt[k].l,v);
if (tt[tt[k].l].rnd<tt[k].rnd) rturn(k);
}
}
void del(int &k,int v){
if (!k) return;
if (tt[k].v==v){
if (tt[k].l*tt[k].r==){
c[++Cnt]=k;
k=tt[k].l+tt[k].r;
all[v]--;
return;
}
if (tt[tt[k].l].rnd<tt[tt[k].r].rnd){
rturn(k);
del(k,v);
}else{
lturn(k);
del(k,v);
}
return;
}
if (tt[k].v<v) del(tt[k].r,v);
else del(tt[k].l,v);
}
int find_treap(int k){
while (tt[k].l!=) k=tt[k].l;
return tt[k].v;
}
bool findit(int k,int x){
if (!k) return ;
if (tt[k].v==x) return ;
else if (tt[k].v<x) return findit(tt[k].r,x);
else return findit(tt[k].l,x);
}
void Gwork(){
Tcase=Tcase;
}
void updata(int x,int id){
if (id==) x=pls[find_treap(rt1[a[x].l])];
else if (id==) x=pls[find_treap(rt2[a[x].r])];
if (a[x].l>a[x].r) return;
segment t1=query(,,Len,a[x].l,a[x].r);
a[x].cnt=t1.v;
if (a[x].id==&&(a[x].l==||a[x].r==)) Gwork();
del(rt1[a[x].l],a[x].id);
del(rt2[a[x].r],a[x].id);
a[x].l=t1.l;
a[x].r=t1.r;
insert(rt1[a[x].l],a[x].id);
insert(rt2[a[x].r],a[x].id);
modify_heap(a[x].id,a[x].cnt);
}
void sbpianfen3(){
for (int i=;i<=n;i++)
a[i].l=read(),a[i].r=read(),a[i].cnt=a[i].r-a[i].l+,a[i].id=i,add_heap(i,a[i].r-a[i].l+),p[++p[]]=a[i].l,p[++p[]]=a[i].r;
std::sort(p+,p++p[]);int j=;
for (int i=;i<=p[];i++)
if (p[i]!=p[j]) p[++j]=p[i];p[]=j;
for (int i=;i<=p[];i++)
if (p[i]!=p[i-]){
o[++sz]=p[i]-p[i-]-;
o[++sz]=;
Id[i]=sz;
}
Len=sz;
for (int i=;i<=n;i++)
a[i].l=find(a[i].l),a[i].r=find(a[i].r),insert(rt1[a[i].l],i),insert(rt2[a[i].r],i);
for (int i=;i<=n;i++)
pls[a[i].id]=i;
for (int i=;i<=n;i++) before[i]=i-;
for (int i=;i<n;i++) next[i]=i+;
int T=n;
build(,,Len);
while (T--){
Tcase++;
int x=heap[];printf("%d\n",x);
delete_heap(x);
if (a[x].l>a[x].r){
int t1=before[pls[x]],t2=next[pls[x]];
next[t1]=t2;
before[t2]=t1;
continue;
}
if (Tcase==) Gwork();
modify(,,Len,a[pls[x]].l,a[pls[x]].r);
if (before[pls[x]]) updata(before[pls[x]],);
if (next[pls[x]]) updata(next[pls[x]],);
int t1=before[pls[x]],t2=next[pls[x]];
next[t1]=t2;
before[t2]=t1;
}
}
int main(){
Len=read();n=read();
if (n<=) {sbpianfen1();fclose(stdin);fclose(stdout);return ;}
sbpianfen3();
fclose(stdin);fclose(stdout);
return ;
}

FJ省队集训DAY3 T1的更多相关文章

  1. FJ省队集训DAY5 T1

    思路:考试的时候打了LCT,自以为能过,没想到只能过80.. 考完一想:lct的做法点数是100W,就算是nlogn也会T. 讲一下lct的做法把:首先如果一条边连接的两个点都在同一个联通块内,那么这 ...

  2. FJ省队集训DAY4 T1

    直接上题解 #include<cstdio> #include<iostream> #include<cmath> #include<cstring> ...

  3. FJ省队集训DAY3 T2

    思路:如果一个DAG要的路径上只要一条边去切掉,那么要怎么求?很容易就想到最小割,但是如果直接做最小割会走出重复的部分,那我们就这样:反向边设为inf,这样最小割的时候就不会割到了,判断无解我们直接用 ...

  4. FJ省队集训DAY2 T1

    思路:转换成n条三维空间的直线,求最大的集合使得两两有交点. 有两种情况:第一种是以某2条直线为平面,这时候只要统计这个平面上有几条斜率不同的直线就可以了 还有一种是全部交于同一点,这个也只要判断就可 ...

  5. FJ省队集训DAY1 T1

    题意:有一堆兔子,还有一个r为半径的圆,要求找到最大集合满足这个集合里的兔子两两连边的直线不经过圆. 思路:发现如果有两个点之间连边不经过圆,那么他们到圆的切线会构成一段区间,那么这两个点的区间一定会 ...

  6. 省队集训Day3 light

    [问题描述] “若是万一琪露诺(俗称 rhl)进行攻击,什么都好,冷静地回答她的问题来吸引她.对方表现出兴趣的话,那就慢慢地反问.在她考虑答案的时候,趁机逃吧.就算是很简单的问题,她一定也答不上来.” ...

  7. 省队集训Day3 tree

    [题目描述] RHL 有一天看到 lmc 在玩一个游戏. “愚蠢的人类哟,what are you doing”,RHL 说. “我在玩一个游戏.现在这里有一个有 n 个结点的有根树,其中有 m 个叶 ...

  8. bzoj4171 or 省队集训day3 chess: Rhl的游戏

    [题目描述] RHL最近迷上一个小游戏:Flip it.游戏的规则很简单,在一个N*M的格子上,有一些格子是黑色,有一些是白色.每选择一个格子按一次,格子以及周围边相邻的格子都会翻转颜色(边相邻指至少 ...

  9. FJ省队集训DAY4 T3

    #include<cstdio> #include<iostream> #include<cmath> #include<cstring> #inclu ...

随机推荐

  1. FFT修正

    #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #inc ...

  2. Linux系统编程(31)—— socket编程之TCP详解

    TCP有源端口号和目的端口号,通讯的双方由IP地址和端口号标识.32位序号.32位确认序号.窗口大小稍后详细解释.4位首部长度和IP协议头类似,表示TCP协议头的长度,以4字节为单位,因此TCP协议头 ...

  3. Java---设计模式app小软件汇总应用

    写了一个app小软件,重点不在于软件,软件bug挺多,也没去修改. 这个小软件只是为了更好的说明和了解设计模块而做的. Java 程序设计–包结构 Java程序设计的系统体系结构很大一部分都体现在包结 ...

  4. Java中快速排序的实现

    快速排序是对冒泡排序的一种改进.它的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要 小,然后再按次方法对这两部分数据分别进行快速排序,整个排 ...

  5. 開始学习swift开发

    近期要開始学习swift开发了,接下来的日子,会记录学习swift的历程.

  6. 关于Javascript语言中this关键字(变量)的用法

    最近很多 Javascript初学者朋友总在问: Javascript 的this 关键字的用法.我在这里索性总结一下 this关键字的用法. this 关键字是面向对象编程语言中的一个重要概念!在J ...

  7. Win7 64位下配置Qt5.3和Wincap

         最近在学网络编程,想在windows下用Qt做个网络抓包工具,就要用到WinPcap,而我的电脑的系统是Win7 64位,qt版本是Qt 5.3.1 for Windows 64-bit ( ...

  8. SQL转换函数to_char/to_date/to_number

    日期型->字符型转换函数to_char(d [,fmt]) 函数to_char(d [,fmt])用于将日期型数值转换为字符串(varchar2类型),其中参数d用于指定日期值,fmt用于指定要 ...

  9. LDAP索引及缓存优化

    一.设置索引 索引将查找信息和 Directory Server 条目关联起来. Directory Server支持以下几种索引: 1出现索引 (pres) - 列出了具有特定属性的条目,与属性的值 ...

  10. bug记录-setTimeout、setInterval之IOS7

    本篇文章主要讲查找并分析bug的思路,相关的函数不是本文的重点. 众所周知,setTimeout和setInterval是用来做延迟调用以及周期性调用的方法,他们支持的参数都差不多. setTimeo ...