• BZOJ 3262 陌上花开 ——CDQ分治


    【题目分析】

        多维问题,我们可以按照其中一维排序,然后把这一维抽象的改为时间。

        然后剩下两维,就像简单题那样,排序一维,树状数组一维,按照时间分治即可。

        挺有套路的一种算法。

        时间的抽象很巧妙。

        同种的花需要处理,合并在一起计算即可。

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #include <algorithm>
     
    using namespace std;
     
    #define ll long long
    #define maxn 300005
     
    struct flo{int a,b,c,id;}q[maxn],eq[maxn],nq[maxn];
    int cnt,k,top=0,ans[maxn],T,c[maxn];
    vector <int> v[maxn];
     
    bool cmp(flo x,flo y)
    {
        if (x.a==y.a&&x.b==y.b) return x.c<y.c;
        if (x.a==y.a) return x.b<y.b;
        return x.a<y.a;
    }
     
    bool cmp2(flo x,flo y)
    {
        if (x.b==y.b&&x.c==y.c) return x.a<y.a;
        if (x.b==y.b) return x.c<y.c;
        return x.b<y.b;
    }
     
    struct Bit_Tree{
        int v[maxn];
        void init(){memset(v,0,sizeof v);}
        void add(int x,int f)
        {for (;x<=k;x+=x&(-x)) v[x]+=f;}
        int sum(int x)
        {
            int ret=0;
            for (;x;x-=x&(-x)) ret+=v[x];
            return ret;
        }
    }t;
     
    void solve(int l,int r)
    {
        if (l==r) return ;
        int mid=(l+r)/2;
        for (int i=l;i<=r;++i)
        {
            if (eq[i].a<=mid) t.add(eq[i].c,v[eq[i].id].size());
            if (eq[i].a>mid)
            {
                int tmp=t.sum(eq[i].c);
                for (int j=0;j<v[eq[i].id].size();++j)
                    ans[v[eq[i].id][j]]+=tmp;
            }
        }
        int p1=l,p2=mid+1;
        for (int i=l;i<=r;++i) if (eq[i].a<=mid) t.add(eq[i].c,-v[eq[i].id].size());
        for (int i=l;i<=r;++i) if (eq[i].a<=mid) nq[p1++]=eq[i]; else nq[p2++]=eq[i];
        for (int i=l;i<=r;++i) eq[i]=nq[i];
        solve(l,mid);
        solve(mid+1,r);
    }
     
    int main()
    {
        scanf("%d%d",&cnt,&k);
        for (int i=1;i<=cnt;++i) scanf("%d%d%d",&q[i].a,&q[i].b,&q[i].c),q[i].id=i;
        sort(q+1,q+cnt+1,cmp);
        for (int i=1;i<=cnt;++i)
        {
            if (!top) eq[++top]=q[i],v[top].push_back(q[i].id);
            else if (eq[top].a!=q[i].a||eq[top].b!=q[i].b||eq[top].c!=q[i].c) eq[++top]=q[i],v[top].push_back(q[i].id);
            else v[top].push_back(q[i].id);
            eq[top].id=top;
        }
        for (int i=1;i<=top;++i) eq[i].a=i;
        sort(eq+1,eq+top+1,cmp2);
        solve(1,top);
        for (int i=1;i<=top;++i)
            for (int j=0;j<v[eq[i].id].size();++j)
                ans[v[eq[i].id][j]]+=v[eq[i].id].size()-1;
        for (int i=1;i<=cnt;++i) c[ans[i]]++;
        for (int i=0;i<cnt;++i) printf("%d
    ",c[i]);
    }
    

      

  • 相关阅读:
    Table Scan, Index Scan, Index Seek
    Ndo v3.1发布了!
    手动建立强类型DataSet
    <.NET分布式应用程序开发>读书笔记 第十章:Q&A
    HQL语法大全
    IT人才最容易犯的几个错误
    在线查询Windows API
    ODP.NET和System.Data.OracleClient的一些不同
    给PDF文件添加链接和书签
    cegui0.6.0的下载、安装、配置及samples浏览
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6231270.html
Copyright © 2020-2023  润新知