排序,三关键字

去重

归并排序+树状数组

#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);
}

最新文章

  1. Laravel中的ajax跨域请求
  2. PowerDesigner设计时表显示注释选项
  3. ASP.NET MVCでResponse Headerのサーバーバージョンをどうやって隠しますか?
  4. BZOJ 2292 永远挑战
  5. 说下Fedora下把SpiderMonkey放入Eclipse内编译的过程
  6. String.Format使用方法
  7. 15. SSH 远程
  8. win10 永久激活 命令行方式
  9. vivado License导入方法与资源获取
  10. scheduling while atomic和bad: scheduling from the idle thread(转)
  11. docker 系列 - Docker CheatSheet | Docker 配置与实践清单 (转载)
  12. 本地构建:Gulp
  13. 神州数码广域网PPP封装PAP认证配置
  14. GoldenGate 12.3 MA架构介绍系列(4)&ndash;Restful API介绍
  15. react添加方法的两种形式
  16. excel合并同类项去重求和功能
  17. Telnet模拟系统(Linux c)
  18. 关于FSMC地址线的理解
  19. 配置新服务器 的一些 依赖库 php mysql nginx
  20. 用ildasm/ilasm修改IL代码(操作步骤)

热门文章

  1. 【转】风控中的特征评价指标(一)——IV和WOE
  2. 提升50%!Presto如何提升Hudi表查询性能?
  3. (转)通过gitlab统计git提交的代码量
  4. Linux的三剑客
  5. 手写Spring MVC框架(二) 实现访问拦截功能
  6. SQLFlow——一个强大的可视化SQL关系分析工具
  7. [Scala] 高级特性
  8. [DB] MySQL 索引分类
  9. Debian 9.4 多网卡链路聚合bond配置
  10. 7.12-7.19 id、w、who、last、lastb、lastlog