CDQ分治
感觉就是整体二分,只不过重命名了。
所以说一下它的实现方式。
套路是定下来一个区间,统一计算左区间端点对右区间的贡献(左右可颠倒)。
然后一直递归到l==r这时跨过每个节点的答案均被统计,不重不漏。
这里放几个模板题:
寒假作业
最纯的分治,实现特别简单,分治,然后排序进行左对右的统计即可。
这里不放码了,占博客空间。
三维偏序
这个题的套路是排序与去重。
考虑去计算贡献,首先要先将一维保证有序。
所以整体按照a为第一关键字,b为第二关键字,c为第三关键字排序。
然后我们用CDQ,考虑跨过中点之后,右端点固定所能够有的贡献。
发现二分后左边的a小于右边的a,所以左右分别按照b排序。
然后将右边界指针按b从小到大扫,同时左边比右指针小的点都有可能造成贡献。
造成贡献当且仅当左边节点的c值<=右指针c值。
所以把这个事情交给树状数组去统计即可。
注意三个值均相同的元素去统计时会出问题,举个极端例子,整个区间两个节点,这俩相同。
这时候你整体二分再统计,得到答案为1的点只有一个,但事实上它有两个答案为1的点。
所以这个时候就要给端点赋值再CDQ统计。
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
#define qr qr()
#define ps push_back
#define pa pair<int,int>
#define ve vector
#define fi first
#define se second
using namespace std;
const int N=2e5+200;
int n,m,c[N],st[N],top,cnt[N],ans[N],tot;
inline ll qr{
ll x=0;char ch=getchar();
while(ch>57||ch<48)ch=getchar();
while(ch>=48&&ch<=57)x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x;
}
struct node{
int a,b,c,ans,val;
}w[N];
bool cmp(node a,node b){
return (a.a==b.a)?((a.b==b.b)?a.c<b.c:a.b<b.b):a.a<b.a;
}
bool cmp2(node a,node b){
return a.b<b.b;
}
inline int ask(int pos){
int res=0;
while(pos)res+=c[pos],pos-=pos&-pos;
return res;
}
inline void update(int pos,int val){
while(pos<=m)c[pos]+=val,pos+=pos&-pos;
}
void solve(int l,int r){
if(l==r)return;
int md=l+r>>1;
solve(l,md);solve(md+1,r);
sort(w+l,w+md+1,cmp2);
sort(w+md+1,w+r+1,cmp2);
top=0;
for(int i=md+1,j=l;i<=r;++i){
while(w[j].b<=w[i].b&&j<=md)update(w[j].c,w[j].val),st[++top]=j,++j;
w[i].ans+=ask(w[i].c);
}for(int i=1;i<=top;++i)update(w[st[i]].c,-w[st[i]].val);
}
void init(){
n=qr;m=qr;
for(int i=1,a,b,c;i<=n;++i)
a=qr,b=qr,c=qr,w[i]={a,b,c};
sort(w+1,w+n+1,cmp);
for(int i=1,c=0;i<=n;++i){
++c;
if(w[i].a!=w[i+1].a||w[i].b!=w[i+1].b||w[i].c!=w[i+1].c)
w[++tot]=w[i],w[tot].val=c,c=0;
}
sort(w+1,w+tot+1,cmp);
solve(1,tot);
for(int i=1;i<=tot;++i)
cnt[w[i].ans+w[i].val-1]+=w[i].val;
for(int i=0;i<n;++i)
cout<<cnt[i]<<'\n';
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
init();
return 0;
}
https://www.cnblogs.com/shining-like-stars

浙公网安备 33010602011771号