题意:

给出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. super 使用以及原理

    用super也很久了,但是一直没有关注过他的原理.最近开始越来越多关注python更底层的实现和奇技淫巧.看到该方法越发使用得多所以也研究了一波 平时单继承可能是我们遇到最多的情况.无非就是类似情况. ...

  2. 将ubuntu14.04 从mysql从5.5删除之后安装5.7遇到的一些问题(本篇不讨论热升级)

    五一放假实在无聊 继续玩弄新的服务器.发现有台mysql版本实在有点老,估计是akiho直接使用 apt-get install mysql-server ,然后又没有更新到最新的源,然后无脑安装了5 ...

  3. 关于EXCEL if、countif 在查找数据的用法

    最近被其他部门的同事教导使用excel.突然觉得以前用代码切来切去的东西,和频繁比对的数据原来是用excel就能那么方便的算出,瞬间感觉打开了新世界的大门. 先说if和countif结合使用,来判断一 ...

  4. html5 sessionStorage VS loaclStorage

    localStorage:沒有時間限制的存儲,數據一致存在 sessionStorage:針對一個session的存儲,會話頁面關閉后,數據被刪除 以前這些都是通過cookie來完成的,但是cooki ...

  5. Java之Logger日志(Java8特性)

    import java.util.logging.Level; import java.util.logging.Logger; public class LoggingDemo { public s ...

  6. BZOJ1115[POI2009]石子游戏——阶梯Nim游戏

    题目描述 有N堆石子,除了第一堆外,每堆石子个数都不少于前一堆的石子个数.两人轮流操作每次操作可以从一堆石子中移走任意多石子,但是要保证操作后仍然满足初始时的条件谁没有石子可移时输掉游戏.问先手是否必 ...

  7. MT【66]寻找对称中心

    设函数$f(x)=2x-cosx,{a_n}$是公差为$\frac{\pi}{8}$的等差数列,$f(a_1)+f(a_2)+f(a_3)+f(a_4)+f(a_5)=5\pi$,则 $[f(a_3) ...

  8. apache 限制连接并发数和下载速度

    apache 限制并发数 需要安装:mod_limitipconn模块 安装方法:yum install mod_limitipconn 安装完成后: 检查 Apache 模块目录,看是否含有 mod ...

  9. Leetcode 347.前K个高频元素 By Python

    给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], ...

  10. 洛谷 P2463 [SDOI2008]Sandy的卡片 解题报告

    P2463 [SDOI2008]Sandy的卡片 题意 给\(n(\le 1000)\)串,定义两个串相等为"长度相同,且一个串每个数加某个数与另一个串完全相同",求所有串的最长公 ...