zoukankan      html  css  js  c++  java
  • 三维偏序(cdq分治)

    第一维对a排序

    第二维归并排序,因为已经按a排过序,在左边和右边对b排序时仍保证左边的a小于右边

    第三维树状数组,查询满足前两位偏序关系,且c小于当前数的个数

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 200010;
    
    int n,k,cnt,ans=0;
    
    struct Node{
        int a,b,c,v,id;
    }a[maxn],b[maxn],lc[maxn],rc[maxn];
    
    int s[maxn],f[maxn],d[maxn];
    
    void add(int x,int v){ for(int i=x;i<=k;i+=i&(-i)) s[i]+=v; }
    int sum(int x){ int res=0; for(int i=x;i>0;i-=i&(-i)) res+=s[i]; return res; }
    void clear(int x){ for(int i=x;i<=k;i+=i&(-i)) s[i]=0; }
    
    bool cmpx(Node a,Node b){ return a.a!=b.a?a.a<b.a:a.b!=b.b?a.b<b.b:a.c<b.c;  }
    bool cmpy(Node a,Node b){ return a.b!=b.b?a.b<b.b:a.c<b.c; }
    
    void cdq(int l,int r){
        if(l==r) return;
        int mid=(l+r)/2;
        cdq(l,mid),cdq(mid+1,r);
        
        for(int i=l;i<=mid;i++) lc[i]=b[i];
        for(int i=mid+1;i<=r;i++) rc[i]=b[i];
    
        sort(lc+l,lc+1+mid,cmpy);
        sort(rc+mid+1,rc+r+1,cmpy);
    
        int p=l,q=mid+1;
        
        while(p<=mid&&q<=r){
            if(lc[p].b<=rc[q].b){
                add(lc[p].c,lc[p].v);
                ++p;
            }
            else{
                f[rc[q].id]+=sum(rc[q].c);
                ++q;
            }
        }
        while(q<=r){
            f[rc[q].id]+=sum(rc[q].c);
            ++q;
        }
    
        for(int i=l;i<=mid;i++){
            clear(lc[i].c);
        }
    }
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f;}
    
    int main(){
        n=read(),k=read();
        for(int i=1;i<=n;i++){ a[i].a=read(),a[i].b=read(),a[i].c=read(),a[i].id=i; }
        sort(a+1,a+1+n,cmpx);
        
        for(int i=1;i<=n;i++){
            if(a[i].a==a[i-1].a&&a[i].b==a[i-1].b&&a[i].c==a[i-1].c){
                ++b[cnt].v;
            }else{
                b[++cnt].a=a[i].a,b[cnt].b=a[i].b,b[cnt].c=a[i].c,b[cnt].id=a[i].id;
                b[cnt].v=1;
            }
        }
    
        
        cdq(1,cnt);
    
        for(int i=1;i<=cnt;i++){
            d[f[b[i].id]+b[i].v-1]+=b[i].v;
        }
        for(int i=0;i<=n-1;i++){
            printf("%d\n",d[i]);
        }
    
        return 0;
    }
  • 相关阅读:
    python--脚本传参与shell脚本传参(位置参数)
    python--一起来盖个时间戳!!
    python--多线程的应用
    python-局域网内实现web页面用户端下载文件,easy!
    java初始化顺序
    java List<String>的初始化 的一个小问题
    java.util.Queue用法
    C#中的struct(结构)为值类型,struct类型全接触
    Java 实例
    git还原某个特定的文件到之前的版本
  • 原文地址:https://www.cnblogs.com/tuchen/p/10487258.html
Copyright © 2011-2022 走看看