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

    偏序问题:

    https://www.luogu.org/blog/Owencodeisking/post-xue-xi-bi-ji-cdq-fen-zhi-hu-zheng-ti-er-fen

    优质题目:

    https://oi.men.ci/tag/cdq/

    看思想:

    https://www.cnblogs.com/MyNameIsPc/p/9297296.html

    https://www.cnblogs.com/mlystdcall/p/6219421.html

    三维偏序

    维度a,b,c

    [m+1,r]对于[l,m]满足条件的个数

    经过排序过,

    a:

    [m+1,r]的任意一个数比[l,m]的任意一个数大

    这一维解决了

    b:

    区间合并时是按照b从小到大添加的

    这一维解决了

    c:

    树状数组记录

    注意:

    1.去掉相同的项

    如果不那么做,如果[m+1,r]中的一项与[l,m]中的一项相同,就会出错。

    2.[l,m]的数值添加到树状数组中,最后要去掉。

    https://loj.ac/problem/112

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <string>
      6 #include <algorithm>
      7 #include <set>
      8 #include <map>
      9 #include <queue>
     10 #include <iostream>
     11 using namespace std;
     12 
     13 #define ll long long
     14 
     15 const int maxn=1e5+10;
     16 const int inf=1e9;
     17 const double eps=1e-8;
     18 const int maxf=2e5+10;
     19 
     20 int maxv,f[maxf],sum[maxn];
     21 
     22 struct node
     23 {
     24     int a,b,c,g,v;///排b,c这两个维度只是为了找到相同的(a,b,c),没有其它的意义
     25     bool operator<(const node &y) const
     26     {
     27         if (a==y.a)
     28         {
     29             if (b==y.b)
     30                 return c<y.c;
     31             return b<y.b;
     32         }
     33         return a<y.a;
     34     }
     35 }d[maxn],e[maxn];
     36 
     37 void update(int x,int y)
     38 {
     39     while (x<=maxv)
     40     {
     41         f[x]+=y;
     42         x+=x&-x;
     43     }
     44 }
     45 
     46 int cal(int x)
     47 {
     48     int sum=0;
     49     while (x)
     50     {
     51         sum+=f[x];
     52         x-=x&-x;
     53     }
     54     return sum;
     55 }
     56 
     57 void cdq(int l,int r)
     58 {
     59     int m=(l+r)>>1;
     60     if (l==r)
     61         return;
     62     cdq(l,m),cdq(m+1,r);
     63     int i,j,k;
     64     for (i=l;i<=r;i++)
     65         d[i]=e[i];
     66     i=l,j=m+1,k=l;
     67     while (i<=m && j<=r)
     68     {
     69         if (d[i].b<=d[j].b)
     70             update(d[i].c,d[i].g),e[k++]=d[i++];
     71         else
     72             d[j].v+=cal(d[j].c),e[k++]=d[j++];
     73     }
     74     while (i<=m)
     75         update(d[i].c,d[i].g),e[k++]=d[i++];
     76     while (j<=r)
     77         d[j].v+=cal(d[j].c),e[k++]=d[j++];
     78     for (i=l;i<=m;i++)
     79         update(d[i].c,-d[i].g);
     80 }
     81 
     82 int main()
     83 {
     84     int n,m,i;
     85     scanf("%d%d",&n,&maxv);
     86     for (i=1;i<=n;i++)
     87         scanf("%d%d%d",&d[i].a,&d[i].b,&d[i].c),d[i].g=1;
     88     sort(d+1,d+n+1);
     89     e[1]=d[1],m=1;
     90     for (i=2;i<=n;i++)
     91         if (d[i].a==d[i-1].a && d[i].b==d[i-1].b && d[i].c==d[i-1].c)
     92             e[m].g++;
     93         else
     94             e[++m]=d[i];
     95     cdq(1,m);
     96     for (i=1;i<=m;i++)
     97         sum[d[i].v+d[i].g-1]+=d[i].g;
     98     for (i=0;i<n;i++)
     99         printf("%d
    ",sum[i]);
    100     return 0;
    101 }
    102 /*
    103 3 100
    104 1 1 1
    105 2 2 2
    106 3 3 3
    107 */

    later

    https://oi.men.ci/bzoj-2253/

    「BZOJ 2253」纸箱堆叠 - CDQ 分治 + DP

  • 相关阅读:
    洛谷T44252 线索_分治线段树_思维题
    css 迷惑的position
    【二次元的CSS】—— 用 DIV + CSS3 画大白(详解步骤)
    直接使用sublime编译stylus
    w3schools网站的HTML教程之HTML编辑器
    【二次元的CSS】—— 纯CSS3做的能换挡的电扇
    《JavaScript Dom编程艺术》读书笔记(二)
    JQuery基础修炼-样式篇
    Vue.js 开发实践:实现精巧的无限加载与分页功能
    web前端教程《每日一题》(1-99)完结
  • 原文地址:https://www.cnblogs.com/cmyg/p/10698408.html
Copyright © 2011-2022 走看看