zoukankan      html  css  js  c++  java
  • [cdq分治][树状数组] Jzoj P4419 hole

    Description

    GFS打算去郊外建所别墅,享受生活,于是他耗费巨资买下了一块风水宝地,但令他震惊的是,一群DSJ对GFS的富贵生活深恶痛绝,决定打洞以搞破坏。
    现在我们简化一下这个问题,在这片土地上会按顺序发生一系列事件。
    ①一只DSJ在(x,y) 这个点打了一个洞。
    ②有着高雅品味GFS想建一个等腰直角三角形的别墅,即由(x,y) ,(x+d,y) ,(x,y+d) 三点围成的三角形,但为了地基的牢固,他想知道当前这块三角形土地内的洞的个数。
    GFS现在对DSJ已经忍无可忍了,请你帮他回答这些询问。
    初始土地上没有洞。GFS毕竟是GFS,你可以认为土地无限大。
     

    Input

    第一行一个整数 n,表示事件数。接下来n行,每行3个非负整数x ,y ,d 。
    d=0 表示DSJ打洞的事件。否则表示GFS建房的询问。

    Output

    对每个询问输出一个整数,表示当时询问的三角形内的洞的个数。
     

    Sample Input

    输入1:
    8
    1 3 0
    1 5 0
    3 6 0
    4 4 0
    2 6 0
    1 5 3
    1 5 4
    1 1 1
    输入2:
    4
    1 5 0
    3 7 0
    2 5 6
    2 3 4

    Sample Output

    输出1:
    3
    3
    0
    输出2:
    1
    0
     

    Data Constraint

    30%的数据n<=3333 。
    另30% 的数据 GFS只会在DSJ打完洞后才开始询问,xi,yi<=333333 。
    100%的数据 1<=n<=88888,xi,yi<=3333333 。

    题解

    • 四维偏序问题,cdq分治,再用树状数组记录一个前缀和

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 using namespace std;
     5 struct edge { int x,y,z,d; }a[900000],b[900000],c1[90000],c2[900000];
     6 int sz[40000000],ans[900000],tot,num,mx,n,x,y,d;
     7 bool cmp(edge x,edge y) { return x.z<y.z||(x.z==y.z&&x.d<y.d); }
     8 bool cmp1(edge x,edge y) { return x.x<=y.x; }
     9 int lowbit(int x) { return x&-x; }
    10 void insert(int x,int y)
    11 {
    12     num=num+y;
    13     for (x;x<=mx;x+=lowbit(x)) sz[x]+=y;
    14 }
    15 int getsum(int x)
    16 {
    17     int k=num;
    18     for (x;x;x-=lowbit(x)) k-=sz[x];
    19     return k;
    20 }
    21 void work(int l,int r)
    22 {
    23     if (l==r) return;
    24     int mid=(l+r)/2,cnt1=0,cnt2=0;
    25     work(l,mid),work(mid+1,r);
    26     for (int i=l;i<=mid;i++) if (!b[i].d) c1[++cnt1]=b[i];
    27     for (int i=mid+1;i<=r;i++) if (b[i].d) c2[++cnt2]=b[i];
    28     if (!cnt1||!cnt2) return;
    29     sort(c1+1,c1+cnt1+1,cmp1),sort(c2+1,c2+cnt2+1,cmp1);
    30     int k=cnt1+1;
    31     for (int i=cnt2;i>=1;i--)
    32     {
    33         while (k>1&&c1[k-1].x>=c2[i].x) insert(c1[--k].y,1);
    34         ans[c2[i].d]+=getsum(c2[i].y-1);
    35     }
    36     for (int i=k;i<=cnt1;i++) insert(c1[i].y,-1);
    37 }
    38 void cdq(int l,int r)
    39 {
    40     if (l==r) return;
    41     int mid=(l+r)/2;
    42     cdq(l,mid),cdq(mid+1,r);
    43     int cnt=0,boo=0;
    44     for (int i=l;i<=mid;i++) if (!a[i].d) b[++cnt]=a[i];
    45     for (int i=mid+1;i<=r;i++) if (a[i].d) b[++cnt]=a[i],boo=1;
    46     if (!boo||!cnt) return;
    47     sort(b+1,b+cnt+1,cmp),work(1,cnt);
    48 }
    49 int main()
    50 {
    51     scanf("%d",&n);
    52     for (int i=1;i<=n;i++)
    53     {
    54         scanf("%d%d%d",&x,&y,&d);
    55         a[i].x=x+1,a[i].y=y+1,a[i].z=x+y+d,mx=max(mx,y+d);
    56         if (d!=0) a[i].d=++tot;
    57     }
    58     cdq(1,n);
    59     for (int i=1;i<=tot;i++) printf("%d
    ",ans[i]);
    60 }
  • 相关阅读:
    C#泛型
    QT QML Keys 处理注意事项
    Ubuntu 16.04 安装 QT Create 5.3.1
    在VMWare中安装了Ubuntu16.04,想要 Win10 中通过 SecureCRT 来操作
    Ubuntu16在VMWare中使用共享文件夹
    QT QLineEdit 获取焦点/获取焦点后全选字符
    QT Layout 布局的重要性
    QT ToolBar 工具栏浮动状态
    QT 格式化字符串功能
    QT 窗体之间(MainWindow 和 Dialog)数据传递
  • 原文地址:https://www.cnblogs.com/Comfortable/p/9511907.html
Copyright © 2011-2022 走看看