排序,三关键字

去重

归并排序+树状数组

#include<bits/stdc++.h>
using namespace std;
#define re register int
const int N=100010;
const int M=200010;
int n,m;
struct node{
int a,b,c,s,res;
bool operator < (node y) const {
if(a==y.a&&b==y.b)return c<y.c;
if(a==y.a)return b<y.b;
return a<y.a;
}
bool operator == (node y) const {
return a==y.a&&b==y.b&&c==y.c;
}
}q[N],w[N];int cnt;
int tr[M+100],ans[N];
void ins(int x,int v){
for(re i=x;i<M;i+=(i&(-i)))tr[i]+=v;
}
int query(int x){
int ret=0;
for(re i=x;i;i-=(i&(-i)))ret+=tr[i];
return ret;
}
void merge_sort(int l,int r){
if(l>=r)return ;
int mid=l+r>>1;
merge_sort(l,mid);
merge_sort(mid+1,r);
int i=l,j=mid+1,k=l;
while(i<=mid&&j<=r){
if(q[i].b<=q[j].b)ins(q[i].c,q[i].s),w[k++]=q[i++];
else q[j].res+=query(q[j].c),w[k++]=q[j++];
}
while(i<=mid)ins(q[i].c,q[i].s),w[k++]=q[i++];
while(j<=r)q[j].res+=query(q[j].c),w[k++]=q[j++];
for(i=l;i<=mid;i++)ins(q[i].c,-q[i].s);
//for(i=1;i<=M;i++)if(tr[i]==0)cout<<tr[i]<<endl;
for(i=l;i<=r;i++)q[i]=w[i];
}
signed main(){
scanf("%d%d",&n,&m);
for(re i=1;i<=n;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
q[i]={a,b,c,1};
}
sort(q+1,q+n+1);
for(re i=1;i<=n;i++){
//cout<<q[i].a<<" "<<q[i].b<<" "<<q[i].c<<" "<<q[i].s<<endl;
if(q[i]==q[i-1])q[cnt].s++;
else q[++cnt]=q[i];
}
/*for(re i=1;i<=cnt;i++){
cout<<q[i].a<<" "<<q[i].b<<" "<<q[i].c<<" "<<q[i].s<<endl;
}*/
merge_sort(1,cnt);
for(re i=1;i<=cnt;i++){
//cout<<q[i].a<<" "<<q[i].b<<" "<<q[i].c<<" "<<q[i].s<<" "<<q[i].res<<endl;
ans[q[i].res+q[i].s-1]+=q[i].s;
}
for(re i=0;i<n;i++)printf("%d\n",ans[i]);
}

关于为什么按照单关键字排序是错误的?

我们很容易认为,a被sort排好了,b被归并排好了,c在树状数组里统计好了

可是你忘记了一点,在向线段树中插入c的时候,我们要确保插入的每一个c所属的节点的a和b都在现在的a,b之前

所以我们必须要按照三关键字排序。。。。

当然这玩意在有些情况下是不成立的(也就是说,在不需要去重的情况下)

我们可以只对某一个关键字进行排序,或者这个关键字是天然排好的-----天使玩偶

所以在某些情况下,我们可以对CDQ分治的算法进行优化,省掉一个nlogn的时间,也就会快很多

还有一个问题,在利用CDQ做题的时候,最好不要设置重复元素,不然会WA的很惨

佳媛姐姐

这个题又为我们提供了关于CDQ分治的做法,就是我们可以去改变归并排序的顺序

就是前序,中序,后序合并,来满足题目的要求

就这道题,如果要是后序的话,我们无论如何都不能把所有情况找全,所以我们就进行中序归并

这样每次都会造成乱序,我们在时间复杂度允许的情况下使用“sort”,如果不行就用“归并”;

这样这道题就愉快的通过了

#include<bits/stdc++.h>
using namespace std;
#define re register int
const int N=100005;
struct node{
int a,maxn,minn,bl;
}q[N];
bool comp0(node x,node y){return x.bl<y.bl;}
bool comp1(node x,node y){return x.maxn<y.maxn;}
bool comp2(node x,node y){return x.a<y.a;}
int n,m;
int tr[N],ans[N];
void add(int x,int v){
for(re i=x;i<=n;i+=(i&(-i)))tr[i]=max(tr[i],v);
}
int query(int x){
int ret=0;
for(re i=x;i;i-=(i&(-i)))ret=max(ret,tr[i]);
return ret;
}
void clear(int x){
for(re i=x;i<=n;i+=(i&(-i))){
if(tr[i]==0)break;
tr[i]=0;
}
}
void merge_sort(int l,int r){
if(l>=r){
ans[q[l].bl]=max(ans[q[l].bl],1);
return ;
}
int mid=l+r>>1;
merge_sort(l,mid);
sort(q+l,q+mid+1,comp1);
sort(q+mid+1,q+r+1,comp2);
//cout<<l<<" "<<mid<<" "<<r<<" "<<q[l].a<<" "<<q[r].a<<endl;
int i=l,j=mid+1;
while(i<=mid&&j<=r){
if(q[i].maxn<=q[j].a)add(q[i].a,ans[q[i].bl]),i++;
else ans[q[j].bl]=max(ans[q[j].bl],query(q[j].minn)+1),j++;
}
while(i<=mid)add(q[i].a,ans[q[i].bl]),i++;
while(j<=r)ans[q[j].bl]=max(ans[q[j].bl],query(q[j].minn)+1),j++;
//cout<<query(q[j-1].minn)<<" "<<q[j-1].minn<<" "<<q[i-1].a<<" "<<ans[q[j-1].bl]<<endl;
for(i=l;i<=mid;i++)clear(q[i].a);
sort(q+l,q+r+1,comp0);
merge_sort(mid+1,r);
}
signed main(){
scanf("%d%d",&n,&m);
for(re i=1;i<=n;i++){
int x;scanf("%d",&x);
q[i].a=x;q[i].maxn=x;q[i].minn=x;q[i].bl=i;
}
for(re i=1;i<=m;i++){
int x,y;scanf("%d%d",&x,&y);
q[x].maxn=max(q[x].maxn,y);
q[x].minn=min(q[x].minn,y);
}
//for(re i=1;i<=n;i++)cout<<i<<" "<<q[i].a<<" "<<q[i].maxn<<" "<<q[i].minn<<endl;
merge_sort(1,n);
int sum=0;
for(re i=1;i<=n;i++)sum=max(sum,ans[i]);
printf("%d",sum);
}

CDQ分治(三维偏序集)的更多相关文章

  1. BZOJ 3262: 陌上花开 [CDQ分治 三维偏序]

    Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...

  2. 洛谷P3810 陌上花开 CDQ分治(三维偏序)

    好,这是一道三维偏序的模板题 当然没那么简单..... 首先谴责洛谷一下:可怜的陌上花开的题面被无情的消灭了: 这么好听的名字#(滑稽) 那么我们看了题面后就发现:这就是一个三维偏序.只不过ans不加 ...

  3. 【算法】CDQ分治 -- 三维偏序 & 动态逆序对

    初次接触CDQ分治,感觉真的挺厉害的.整体思路即分而治之,再用之前处理出来的答案统计之后的答案. 大概流程是(对于区间 l ~ r): 1.处理 l ~mid, mid + 1 ~ r 的答案: 2. ...

  4. NEUOJ 1702:撩妹全靠魅力值(CDQ分治三维偏序)

    http://acm.neu.edu.cn/hustoj/problem.php?id=1702 思路:三维偏序模板题,用CDQ分治+树状数组或者树套树.对于三元组(x,y,z),先对x进行排序,然后 ...

  5. cdq分治·三维偏序问题

    转载自FlashHu大佬的博客CDQ分治总结(CDQ,树状数组,归并排序),在讲述部分有部分删改,用了自己的代码 CDQ分治的思想 CDQ分治是基于时间的离线分治算法.这一类分治有一个重要的思想——用 ...

  6. CDQ分治 三维偏序

    这应该是一道CDQ分治的入门题目 我们知道,二维度的偏序问题直接通过,树状数组就可以实现了,但是三维如何实现呢? 我记得以前了解过一个小故事,应该就是分治的. 一个皇帝,想给部下分配任务,但是部下太多 ...

  7. BZOJ 2244: [SDOI2011]拦截导弹 (CDQ分治 三维偏序 DP)

    题意 略- 分析 就是求最长不上升子序列,坐标取一下反就是求最长不下降子序列,比较大小是二维(h,v)(h,v)(h,v)的比较.我们不看概率,先看第一问怎么求最长不降子序列.设f[i]f[i]f[i ...

  8. BZOJ.1935.[SHOI2007]Tree园丁的烦恼(CDQ分治 三维偏序)

    题目链接 矩形查询可以拆成四个点的前缀和查询(树套树显然 但是空间不够) 每个操作表示为(t,x,y),t默认有序,对x分治,y用树状数组维护 初始赋值需要靠修改操作实现. //119964kb 43 ...

  9. BZOJ.3262.陌上花开([模板]CDQ分治 三维偏序)

    题目链接 BZOJ3262 洛谷P3810 /* 5904kb 872ms 对于相邻x,y,z相同的元素要进行去重,并记录次数算入贡献(它们之间产生的答案是一样的,但不去重会..) */ #inclu ...

  10. BZOJ - 1935 / 1176 cdq分治 三维偏序

    题意:给定n*m的网格,且给出n个(x,y)表示该网格已被占有,q次询问(x1,y1)到(x2,y2)的网格中有多少个被占有,n,m范围1e7,q范围5e5 cdq按x轴排序,树状数组维护y轴 #in ...

随机推荐

  1. layui中流加载layui.flow

    1.引入layui.css和layui.js 2. html中定义容器 <div id="demo"></div> js部分: layui.use('flo ...

  2. 基于 registry 搭建 Docker 私有镜像仓库

    今天主要介绍使用 registry 来搭建 Docker私有镜像仓库,方便在公司内部项目中使用,registry 也是 Docker 官方提供的一个镜像,操作也很简单. dockerhub: http ...

  3. Hive企业级性能优化

    Hive作为大数据平台举足轻重的框架,以其稳定性和简单易用性也成为当前构建企业级数据仓库时使用最多的框架之一. 但是如果我们只局限于会使用Hive,而不考虑性能问题,就难搭建出一个完美的数仓,所以Hi ...

  4. Asp.NetCore Web开发之Nlog日志配置

    接着讲基于ASP .net Core 的web开发,这节主要讲一下如何使用和配置Nlog进行日志记录. 日志在开发中的作用是很重要的,使用日志,程序出了错误可以及时捕获并记录下来,开发人员可以通过日志 ...

  5. SparkSQL电商用户画像(四)之电商用户画像数据仓库建立

    六.  电商用户画像数据仓库建立 7.1  数据仓库准备工作 为什么要对数据仓库分层?星型模型 雪花模型 User----->web界面展示指标表 l    用空间换时间,通过大量的预处理来提升 ...

  6. Codeforces Round #713 (Div. 3)AB题

    Codeforces Round #713 (Div. 3) Editorial 记录一下自己写的前二题本人比较菜 A. Spy Detected! You are given an array a ...

  7. unbuntu下清理磁盘空间

    把很多大文件删除,并清空回收站后,发现可用存储空间并没增大,如图: 用find /home -size +500k 过滤出大于500k bytes的文件,发现原来删除的yuv文件都被置于.cache目 ...

  8. BugkuCTF——wp(旧版)

    title: BugkuCTF--wp(旧版) date: 2020-4-25 tags: CTF,比赛 categories: CTF 比赛 Web篇 0x001-web2 解题思路: 1.直接按F ...

  9. Apache Hudi集成Spark SQL抢先体验

    Apache Hudi集成Spark SQL抢先体验 1. 摘要 社区小伙伴一直期待的Hudi整合Spark SQL的PR正在积极Review中并已经快接近尾声,Hudi集成Spark SQL预计会在 ...

  10. Jmeter(四十五) - 从入门到精通高级篇 - Jmeter之网页爬虫-上篇(详解教程)

    1.简介 上大学的时候,第一次听同学说网页爬虫,当时比较幼稚和懵懂,觉得就是几只电子虫子爬在网页上在抓取东西.后来又听说写代码可以实现网页爬虫,宏哥感觉高大上,后来工作又听说,有的公司做爬虫被抓的新闻 ...