zoukankan      html  css  js  c++  java
  • [bzoj1176]Mokia[CDQ分治]

    啃了一天论文,发现CDQ分治的原理其实很简单,大概就是这样的一类分治:将左右区间按一定规律排序后分开处理,递归到底时直接计算答案,对于一个区间,按照第二关键字split成两个区间,先处理左区间,之后因为整个区间是有序的,就可以根据左区间来推算右区间的答案,最后递归处理右区间即可。拿此题做比方,先把全区间按照x坐标排序,然后自左向右用前一半(按时间排序)的修改来更新后一半的查询,之后将整个区间按照时间分成两个部分,递归处理。归纳起来就是split->left->push->right->merge->return。

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <ctime>
     7 #include <cmath>
     8 
     9 using namespace std;
    10 
    11 struct node { int    v,x,y,op,d,pos; }a[210000],temp[210000];
    12 
    13 int    s,w,cnt;
    14 int    L[2100000],Ans[11000];
    15 
    16 bool    operator<(const node temp1,const node temp2)
    17 {
    18     if(temp1.x!=temp2.x)return temp1.x<temp2.x;
    19     if(temp1.y!=temp2.y)return temp1.y<temp2.y;
    20     return temp1.op<temp2.op;
    21 }
    22 
    23 void    Add(const int x,const int d) { for(int i=x;i<=w;i+=i&-i)L[i]+=d; return ; }
    24 int    Query(const int x) { int t=0; for(int i=x;i;i-=i&-i) t+=L[i]; return t; }
    25 
    26 void    CDQ(const int l,const int r)
    27 {
    28     if(l==r)return ;
    29 
    30     int    i,mid=l+((r-l)>>1);
    31 
    32     for(i=l;i<=r;++i)
    33     {
    34         if(a[i].v<=mid && a[i].op==0)Add(a[i].y,a[i].d);
    35         if(a[i].v>mid  && a[i].op==1)Ans[a[i].pos]+=Query(a[i].y)*a[i].d;
    36     }
    37     for(i=l;i<=r;++i)
    38         if(a[i].v<=mid && a[i].op==0)Add(a[i].y,-a[i].d);
    39 
    40     int l1=l,l2=mid+1;
    41     for(i=l;i<=r;++i)
    42     {
    43         if(a[i].v<=mid)temp[l1++]=a[i];
    44         else    temp[l2++]=a[i];
    45     }
    46     for(i=l;i<=r;++i)a[i]=temp[i];
    47     CDQ(l,mid),CDQ(mid+1,r);
    48     return ;
    49 }
    50 
    51 
    52 int main()
    53 {
    54     int    i,op,x,y,z,xa,xb,ya,yb;
    55 
    56     scanf("%d%d",&s,&w);
    57     while(1)
    58     {
    59         scanf("%d",&op);
    60         if(op==1)
    61         {
    62             scanf("%d%d%d",&x,&y,&z);
    63             a[++cnt]=(node){cnt,x,y,0,z,0};
    64         }
    65         else if(op==2)
    66         {
    67             scanf("%d%d%d%d",&xa,&ya,&xb,&yb);
    68             a[++cnt]=(node){cnt,xb  ,yb  ,1,+1,++Ans[0]};
    69             a[++cnt]=(node){cnt,xb  ,ya-1,1,-1,Ans[0]};
    70             a[++cnt]=(node){cnt,xa-1,yb  ,1,-1,Ans[0]};
    71             a[++cnt]=(node){cnt,xa-1,ya-1,1,+1,Ans[0]};
    72         }
    73         else    break;
    74     }
    75 
    76     sort(a+1,a+cnt+1);
    77 
    78     CDQ(1,cnt);
    79 
    80     for(i=1;i<=Ans[0];++i)
    81         printf("%d
    ",Ans[i]);
    82 
    83     return 0;
    84 }
  • 相关阅读:
    单据的多个状态字段
    Win7 如何阻止程序联网
    强制关机.bat
    Delphi Class of
    坐标转换 GetCursorPos与转换
    Delphi 的RTTI机制浅探-2
    Delphi 的RTTI机制浅探-1
    Delphi 的RTTI机制-3
    Delphi 的RTTI机制-2
    Delphi 的RTTI机制-1
  • 原文地址:https://www.cnblogs.com/Gster/p/5090536.html
Copyright © 2011-2022 走看看