题意:

给出n个三元组 e[i]=(si,ti,wi)

第i个三元组的价值为 Σ w[j] ,j 满足以下4个条件:

1、j<i

2、tj<ti

3、sj<si

4、不存在j<k<i,且sj<sk<si

把每个三元组看作二维平面上的一个点(i,si)

先不考虑t,

那么j若满足要求,必须满足以(j,sj)为左下角,以(i,si)为右上角的矩形内没有其他的三元组

可以用CDQ分治解决

设三元组e[i]的坐标为(x,y)=(i,si)

先将所有的三元组按s排序,然后按x归并

即左右两边归并时,左边所有三元组的y小于右边所有三元组的s

归并结束后,左右两边合并为x递增的集合

考虑左边对右边的贡献

在归并的过程中维护两个单调栈l和r

栈l 维护左边的三元组,满足x单调递增,y单调递减

栈r 维护右边的三元组,满足x单调递增,y单调递增,且栈顶的y一定小于当前的y

对于右边的一个三元组j,左边对其有贡献的三元组i满足

1、i<j,因为是按x归并,所以此条件一定满足

2、i在栈l中,如果i不在栈l中,说明i后面,j前面存在一个k,满足si<sk<sj

3、设栈r的栈顶为k,i>k,否则这个k会使 i<k<j 且si<sk<sj

我们只维护栈l中三元组的信息,即可满足条件2

至于条件3,因为栈l的x单调递增,二分查找第一个满足条件的,那么它到栈l的栈顶都满足条件

记录栈l中w的前缀和即可解决

现在再考虑t,只需要将前缀和改为可持久化权值线段树即可

#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; #define N 50001 int n;
struct node
{
int s,t,w;
int id;
int ans;
}e[N],g[N],stl[N],str[N]; int has[N]; bool cmpy(node p,node q)
{
return p.s<q.s;
} bool cmpx(node p,node q)
{
return p.id<q.id;
} namespace Segment
{
int tot,rt_id;
int root[N]; int sum[N*],lc[N*],rc[N*]; void pre()
{
tot=rt_id=;
} int query(int x,int y,int l,int r,int opr)
{
if(r<=opr) return sum[y]-sum[x];
int mid=l+r>>;
int res=query(lc[x],lc[y],l,mid,opr);
if(opr>mid) res+=query(rc[x],rc[y],mid+,r,opr);
return res;
} int insert(int x,int l,int r,int pos,int w)
{
int num=++tot;
sum[num]=sum[x];
lc[num]=lc[x];
rc[num]=rc[x];
sum[num]+=w;
if(l==r) return num;
int mid=l+r>>;
if(pos<=mid) lc[num]=insert(lc[x],l,mid,pos,w);
else rc[num]=insert(rc[x],mid+,r,pos,w);
return num;
} int get(int L,int R,int lim)
{
if(L>R || !lim) return ;
return query(root[L-],root[R],,n,lim);
} void del()
{
tot=root[rt_id]-;
rt_id--;
} void add(int pos,int w)
{
rt_id++;
root[rt_id]=insert(root[rt_id-],,n,pos,w);
}
}; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void init()
{
read(n);
for(int i=;i<=n;++i)
{
read(e[i].s); read(e[i].t); read(e[i].w);
e[i].id=i;
}
for(int i=;i<=n;++i) has[i]=e[i].s;
sort(has+,has+n+);
for(int i=;i<=n;++i) e[i].s=lower_bound(has+,has+n+,e[i].s)-has;
for(int i=;i<=n;++i) has[i]=e[i].t;
sort(has+,has+n+);
for(int i=;i<=n;++i) e[i].t=lower_bound(has+,has+n+,e[i].t)-has;
} void solve(int l,int r)
{
if(l==r) return;
int mid=l+r>>;
solve(l,mid);
solve(mid+,r);
int topl=,topr=;
int i=l,j=mid+,tmp=l;
Segment::pre();
while(i<=mid || j<=r)
{
if(j<=r && ( i>mid || e[j].id<e[i].id))
{
while(topr && str[topr].s>e[j].s) topr--;
int pos=lower_bound(stl+,stl+topl+,str[topr],cmpx)-stl;
e[j].ans+=Segment::get(pos,Segment::rt_id,e[j].t-);
str[++topr]=e[j];
g[tmp++]=e[j++];
}
else
{
while(topl && stl[topl].s<e[i].s)
{
Segment::del();
topl--;
}
Segment::add(e[i].t,e[i].w);
stl[++topl]=e[i];
g[tmp++]=e[i++];
}
}
for(int k=l;k<=r;++k) e[k]=g[k];
} int main()
{
freopen("rehearsal.in","r",stdin);
freopen("rehearsal.out","w",stdout);
init();
sort(e+,e+n+,cmpy);
solve(,n);
sort(e+,e+n+,cmpx);
for(int i=;i<=n;++i) printf("%d\n",e[i].ans);
}

cdqz2017-test10-rehearsal(CDQ分治&可持久化线段树&单调栈)的更多相关文章

  1. BZOJ 3956: Count 主席树 可持久化线段树 单调栈

    https://www.lydsy.com/JudgeOnline/problem.php?id=3956 从描述可以得到性质: 每个好点对 ( 除了差值为1的好点对 ) 中间的数 ( i , j ) ...

  2. Codeforces 1175F - The Number of Subpermutations(线段树+单调栈+双针/分治+启发式优化)

    Codeforces 题面传送门 & 洛谷题面传送门 由于这场的 G 是道毒瘤题,蒟蒻切不动就只好来把这场的 F 水掉了 看到这样的设问没人想到这道题吗?那我就来发篇线段树+单调栈的做法. 首 ...

  3. Codeforces 781E Andryusha and Nervous Barriers 线段树 单调栈

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF781E.html 题目传送门 - CF781E 题意 有一个矩形,宽为 w ,高为 h .一开始会有 w 个 ...

  4. 洛谷P4425 转盘 [HNOI/AHOI2018] 线段树+单调栈

    正解:线段树+单调栈 解题报告: 传送门! 1551又是一道灵巧连题意都麻油看懂的题,,,,所以先解释一下题意好了,,,, 给定一个n元环 可以从0时刻开始从任一位置出发 每次可以选择向前走一步或者在 ...

  5. 线段树+单调栈+前缀和--2019icpc南昌网络赛I

    线段树+单调栈+前缀和--2019icpc南昌网络赛I Alice has a magic array. She suggests that the value of a interval is eq ...

  6. 牛客多校第四场sequence C (线段树+单调栈)

    牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...

  7. 【xsy2818】 最近点 动态树分治+可持久化线段树

    题目大意:给你一颗n个节点的树,最初点集S为空. 有m次操作:往当前点集S中加入/删除一个点,询问点x至集合S中任意点的最小距离,回到第t次修改点集的操作后的状态. 数据范围:$n,m≤10^5$ 我 ...

  8. [BZOJ4700]适者(CDQ分治+DP/李超线段树)

    如果没有秒杀,就是经典的国王游戏问题,按t/a从小到大排序即可. 考虑删除两个数i<j能给答案减少的贡献:S[i]*T[i]+P[i-1]*A[i]-A[i]+S[j]*T[j]+P[j-1]* ...

  9. AtCoder Regular Contest 063 F : Snuke’s Coloring 2 (线段树 + 单调栈)

    题意 小 \(\mathrm{C}\) 很喜欢二维染色问题,这天他拿来了一个 \(w × h\) 的二维平面 , 初始时均为白色 . 然后他在上面设置了 \(n\) 个关键点 \((X_i , Y_i ...

随机推荐

  1. ODAC 下载

    官网地址: https://www.oracle.com/technetwork/topics/dotnet/downloads/odacdev-4242174.html 官方说说明: ODAC 18 ...

  2. Oracle测试环境参数调整.

    测试环境上面Oracle数据库性能参数设置 1. 关闭回收站 alter system set recyclebin=off 2. 修改redo日志的大小 11g的默认大小是50m 如果redo fi ...

  3. Win2016以及win10 IIS10 下安装IEwebcontrol的方法

    1. 公司产品需要安装IE webcontrol控件 但是在win2016以及win10 上面安装时 因为IIS 已经升级到了IIS10 安装时会提示: 兼容解决的方法比较简单,修改注册表即可 HKE ...

  4. scope 前缀开头的方法

    https://learnku.com/docs/laravel/5.6/eloquent/1403 本地范围 本地范围允许定义通用的约束集合以便在应用中复用. 例如, 你可能经常需要获取「受欢迎的」 ...

  5. 几种实现one-hot编码的方式

    方法1 之前写使用sklearn进行数据挖掘-房价预测(4)-数据预处理一文中处理标签类特征时候已经提到过,使用sklearn中提供的LabelEncoder和OneHotEncoder方法 a = ...

  6. Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 7. 条件循环

    条件循环能够让程序在条件成立时(即为真时)重复执行循环体中的语句.如果条件一直成立(即永远不会为假),则循环会一直进行下去,不会停止.如果初始时,条件不成立,则循环 1 次也不会执行.Python 中 ...

  7. linux ubuntu nethogs安装与介绍

    安装nethogs: apt-get -y install ncurses* apt-get -y install libpcap-dev libncurses5-dev wget -c https: ...

  8. Java 数组实现 stack

    首先定义 IStack package cn.com.example.stack; /** * Created by Jack on 2017/3/8. */ public interface ISt ...

  9. 04 自学Aruba之定制AC的protal认证登陆页面

    点击返回:自学Aruba之路 04 自学Aruba之定制AC的protal认证登陆页面 方法一: 使用Aruba控制器中内置的网页界面 Configuration下MANAGEMENT>Capt ...

  10. 05 自学Aruba之AAA profile无法删除问题

    点击返回:自学Aruba之路 05 自学Aruba之AAA profile无法删除问题 在新建完成AAA profile之后,可能存在后续不需要或者变动,那就要删除多余的AAA profile . 其 ...