• 【Luogu 3810】三维偏序


    【原题链接】传送门

    【题解大意】

    三个月之前学cdq分治的时候水过去了,三个月之后我连cdq分治是啥都忘了。

    其实实现还是简单的吧,然而某傻逼还是调了好久,最后心态崩掉重码一遍的时候突然发现小于号是不是定义错了。莫队。。。

    【code】

    #include<bits/stdc++.h>
    using namespace std;
    #define File "test"
    #define ll long long
    #define ull unsigned long long
    inline void file(){
        freopen(File".in","r",stdin);
        freopen(File".out","w",stdout);
    }
    inline int read(){
        int x=0,f=1;   char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();}
        return x*f;
    }
    const int mxn = 1e5+5;
    int n,K;
    struct P{
        int a,b,c,w,ans;
        friend bool operator <(P x,P y){
            if(x.a!=y.a) return x.a<y.a;
            if(x.b!=y.b) return x.b<y.b;
            return x.c<y.c;
        }
        friend bool operator ==(P x,P y){
            return x.a==y.a&&x.b==y.b&&x.c==y.c;
        }
    }p[mxn];
    int c[mxn<<1],ans[mxn];
    inline bool cmp(P x,P y){
        return x.b==y.b? x.c<y.c : x.b<y.b;
    }
    inline int lowbit(int x){
        return x&(-x);
    }
    inline void add(int x,int d){
        for(x;x<=K;x+=lowbit(x)) c[x] += d;
    }
    inline int get(int x){
        int ans(0);
        while(x) ans+=c[x],x-=lowbit(x);
        return ans;
    }
    inline void cdq(int l,int r){
        if(l==r) return;
        int m = (l+r) >>1;
        cdq(l,m),cdq(m+1,r);
        
        sort(&p[l],&p[m+1],cmp);
        sort(&p[m+1],&p[r+1],cmp);
    
        int i = l;
        for(int j = m+1;j <= r; ++j){
            while(i<=m && p[i].b<=p[j].b) add(p[i].c,p[i].w),++i;
            p[j].ans += get(p[j].c);
        }
        for(int j = l;j < i; ++j) add(p[j].c,-p[j].w);
    }
    int main(){
    //    file();
        n = read(),K = read();
        for(int i = 1;i <= n; ++i) p[i].a = read(),p[i].b = read(),p[i].c = read();
        sort(&p[1],&p[n+1]);
        int tot(0);
        for(int i = 1;i <= n; ++i){
            if(p[i]==p[i-1]) ++p[tot].w;
            else p[++tot] = p[i],p[tot].w++;
        }
        cdq(1,tot);
        for(int i = 1;i <= tot; ++i) printf("%d %d",p[i].w,p[i].ans);
        for(int i = 1;i <= tot; ++i) ans[p[i].ans+p[i].w] += p[i].w;
        for(int i = 1;i <= n; ++i) printf("%d
    ",ans[i]);
        return 0;
    }
    /*
    10 3
    3 3 3
    2 3 3
    2 3 1
    3 1 1
    3 1 2
    1 3 1
    1 1 2
    1 2 2
    1 3 2
    1 2 1
    */
    /*
    3
    1
    3
    0
    1
    0
    1
    0
    0
    1
    */
    View Code
  • 相关阅读:
    模拟22
    模拟21
    模拟20
    模拟19
    晚测11
    Redis 内存模型
    Redis AOF重写
    基础省选题选做
    八年级上 期中考试祭
    P2049 魔术棋子 题解
  • 原文地址:https://www.cnblogs.com/ve-2021/p/10844508.html
Copyright © 2020-2023  润新知