博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P2184 【贪婪大陆】
阅读量:5275 次
发布时间:2019-06-14

本文共 1049 字,大约阅读时间需要 3 分钟。

看到全是线段树或者树状数组写法,就来提供一发全网唯一cdq分治三维偏序解法吧

容易发现,这个题的查询就是对于每个区间l,r,查询有多少个修改区间li,ri与l,r有交集
转化为数学语言,就是查询满足li<=r且ri>=l的修改个数
一个二维偏序问题,但是我们发现,这是个动态插入的二维偏序问题
_(:з」∠)_一时不知所措
再想一想,不妨把时间另开一个维度作为第三维,然后就是这样了
对于每个查询,我们要求出它之前有多少个修改区间与其相交
数学语言:
查询满足li<=r且ri>=l且[li,ri].time<[l,r].time的修改个数
思路清晰明了,而且敲好想,但是实现细节还是比较麻烦的(一部分是因为我的奇葩cdq写法),在代码注释里解释一下(模板这种的就不解释了)

#include
#include
#include
#include
using namespace std;const int maxn=1e5+10;struct node{ int a,b,c,q,w;//a,b,c表示三个维度,q记录这个操作是修改还是查询//w表示这个是否有效(和q差不多,查询是不需要统计的,w=0;修改的w=1)}v[maxn];int n,m,cnt,tot,c[maxn],ans[maxn];bool vis[maxn];bool cmpx(const node &a,const node &b){ return a.a==b.a?(a.b==b.b?a.c
>1; cdq(l,mid),cdq(mid+1,r); sort(v+l,v+mid+1,cmpy),sort(v+mid+1,v+r+1,cmpy); int i=l,j=mid+1; for(;j<=r;j++) { while(v[i].b<=v[j].b&&i<=mid) add(v[i].c,v[i].w),i++; if(v[j].q==2) ans[v[j].a]+=sum(n)-sum(v[j].c-1); //统计贡献到ans数组中 } for(j=l;j

 

转载于:https://www.cnblogs.com/ivanovcraft/p/9692861.html

你可能感兴趣的文章
如何阅读大型前端开源项目的源码(转)
查看>>
java.util.Arrays类详解
查看>>
NYOJ-626-intersection set(二分查找)
查看>>
项目管理之路(1):初步踏入项目管理
查看>>
Java 中 静态方法与非静态方法的区别
查看>>
echarts饼图显示百分比
查看>>
JMS消息
查看>>
Jenkins+ProGet+Windows Batch搭建全自动的内部包(NuGet)打包和推送及管理平台
查看>>
php上传文件及头像预览
查看>>
大四java实习生的一些经历
查看>>
线程池的概念
查看>>
Oracle_Statspack性能诊断工具
查看>>
Java 序列化
查看>>
Java 时间处理实例
查看>>
Java 多线程编程
查看>>
Java 数组实例
查看>>
mysql启动过程
查看>>
2017前端面试题总结
查看>>
Http GetPost网络请求
查看>>
SWIFT国际资金清算系统
查看>>