• HDU 5618 Jam's problem again CDQ分治 BC ROUND 70


    题意:给你1e5个点(x,y,z),对于每一个点询问有多少个点(x1,y1,z1)满足x1<=x&&y1<=y&&z1<=z

    分析:(官方题解奉上)很显然让你找(x,y,z)(x,y,z)都大于别的(x,y,z)(x,y,z),当然厉害的人可以用树套树水一下,但正解写的是CDQ分治,以xx为第一关键字排序,以yy为第二关键字来找,以zz为第三关键字建一个树状数组找就好了,当然等于的情况可以实现前做一下。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <map>
    #include <set>
    #include <stack>
    #include <queue>
    #include <string>
    using namespace std;
    typedef long long LL;
    const int maxn=1e5+5;
    struct BIT
    {
        int c[maxn];
        void init()
        {
            memset(c,0,sizeof(c));
        }
        int lowbit(int x)
        {
            return x&(-x);
        }
        void add(int x,int t)
        {
            while(x<=1e5)
            {
                c[x]+=t;
                x+=lowbit(x);
            }
        }
        int sum(int x)
        {
            int ans=0;
            while(x>0)
            {
                ans+=c[x];
                x-=lowbit(x);
            }
            return ans;
        }
    } bit;
    struct Node
    {
        int x,y,z,id;
    } o[maxn],tem[maxn];
    bool cmp(Node a,Node b)
    {
        if(a.x!=b.x)
        return a.x<b.x;
        if(a.y!=b.y)
         return a.y<b.y;
       return a.z<b.z;
    }
    bool cmp1(Node a,Node b)
    {
        return a.y<b.y;
    }
    int res[maxn];
    void solve(int l,int r)
    {
        if(l==r)return;
        int m=(l+r)>>1;
        for(int i=l; i<=r; ++i)
            tem[i]=o[i];
        sort(tem+l,tem+m+1,cmp1);
        sort(tem+m+1,tem+r+1,cmp1);
        int cnt=l;
        for(int i=m+1; i<=r; ++i)
        {
            while(cnt<=m&&tem[cnt].y<=tem[i].y)bit.add(tem[cnt].z,1),cnt++;
            res[tem[i].id]+=bit.sum(tem[i].z);
        }
        for(int i=l; i<cnt; ++i)
            bit.add(tem[i].z,-1);
        solve(l,m);
        solve(m+1,r);
    }
    int main()
    {
        int T,n;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            bit.init();
            for(int i=1; i<=n; ++i)
                scanf("%d%d%d",&o[i].x,&o[i].y,&o[i].z),o[i].id=i;
            sort(o+1,o+1+n,cmp);
            memset(res,0,sizeof(res));
            solve(1,n);
            for(int i=n-1; i>0; --i)
                if(o[i].x==o[i+1].x&&o[i].y==o[i+1].y&&o[i].z==o[i+1].z)
                    res[o[i].id]=res[o[i+1].id];
            for(int i=1; i<=n; ++i)
                printf("%d
    ",res[i]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    透明数据加密 (TDE)常见问题解答
    oracle wallet使用与维护
    Mybatis 一对一、一对多、多对一
    Mybatis-Plus
    eclipse安装spring boot插件spring tool suite
    springboot在idea实现热部署
    springboot在eclipse实现热部署
    SpringBoot配置文件-application.properties详解
    Dubbo入门
    Shell入门
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5181515.html
Copyright © 2020-2023  润新知