zoukankan      html  css  js  c++  java
  • bzoj1176 2683

    我的第一道cdq分治题
    清明做了一下cdq分治的几道题,感觉这个东西实在是太厉害了
    离线大法好!关于几个经典的非数据结构做法具体可以看xhr神犇2013年的论文
    应用cdq分治的前提条件是不强制在线,修改操作互不影响。
    什么是互相影响,比如在第i个数后面插入一个数,这就明显是会影响到后面的操作
    在这个前提条件下,我们可以按照操作序列的时间线(先后)划分成两个规模缩小一半的子问题
    显然后面的修改对前面无影响,而后半部分的修改对后半部分的询问、前半部分对前半部分的询问是子问题,可以递归解决
    所以下面我们只要解决前半部分的所有修改操作对后半部分询问答案的贡献即可
    注意这里其实就相当于给出初始值不断进行无修改询问
    也就是我们通过分治(1个log的代价,根据主定理可知),干掉了动态修改
    回到这题上来,由于矩阵很大,不能支持二维数据结构,并且满足前提条件,所以用cdq分治
    之后就变成了给定矩阵上一些值,求子矩阵和这样一个无修改的问题
    注意这里询问满足减法性质,于是可以拆成四个询问,很显然对x排序,对y维护树状数组即可
    具体做法间见程序注释(如果已经懂得了分治的框架写起来是非常轻松的)
    注意bzoj1176和2683空间和范围略有不同

      1 type node=record
      2        op,ch,w,x,y:longint;
      3      end;
      4 
      5 var c:array[0..2000010] of longint;
      6     a,q:array[0..210010] of node;
      7     ans:array[0..10010] of longint;
      8     ch,pre,i,n,m,x,y,x1,y1,t:longint;
      9 
     10 function lowbit(x:longint):longint;
     11   begin
     12     exit(x and (-x));
     13   end;
     14 
     15 function cmp(a,b:node):boolean;  //注意这里要三个关键字排序,x,y,修改优先,为什么要自己想想
     16   begin
     17     if a.x<b.x then exit(true)
     18     else if a.x=b.x then
     19     begin
     20       if a.y<b.y then exit(true)
     21       else if (a.y=b.y) and (a.op<b.op) then exit(true);
     22     end;
     23     exit(false);
     24   end;
     25 
     26 procedure swap(var a,b:node);
     27   var c:node;
     28   begin
     29     c:=a;
     30     a:=b;
     31     b:=c;
     32   end;
     33 
     34 procedure sort(l,r:longint);
     35   var i,j:longint;
     36       x:node;
     37   begin
     38     i:=l;
     39     j:=r;
     40     x:=q[(l+r) shr 1];
     41     repeat
     42       while cmp(q[i],x) do inc(i);
     43       while cmp(x,q[j]) do dec(j);
     44       if not(i>j) then
     45       begin
     46         swap(q[i],q[j]);
     47         inc(i);
     48         dec(j);
     49       end;
     50     until i>j;
     51     if l<j then sort(l,j);
     52     if i<r then sort(i,r);
     53   end;
     54 
     55 procedure add(x,w:longint);
     56   begin
     57     while x<=t do
     58     begin
     59       inc(c[x],w);
     60       x:=x+lowbit(x);
     61     end;
     62   end;
     63 
     64 function ask(x:longint):longint;
     65   begin
     66     ask:=0;
     67     while x>0 do
     68     begin
     69       ask:=ask+c[x];
     70       x:=x-lowbit(x);
     71     end;
     72   end;
     73 
     74 procedure cdq(l,r:longint);
     75   var m,i,l1,l2:longint;
     76   begin
     77     if l=r then exit;
     78     m:=(l+r) shr 1;
     79     for i:=l to r do  
     80     begin
     81       if (q[i].ch<=m) and (q[i].op=-2) then add(q[i].y,q[i].w);  //前半部分修改
     82       if (q[i].ch>m) and (q[i].op<>-2) then inc(ans[q[i].w],ask(q[i].y)*q[i].op);  //对后半部分查询影响
     83     end;
     84     for i:=l to r do  //树状数组清0
     85       if (q[i].ch<=m) and (q[i].op=-2) then add(q[i].y,-q[i].w);
     86     l1:=l; l2:=m+1;
     87     for i:=l to r do  //按时间划分操作序列
     88       if q[i].ch<=m then
     89       begin
     90         a[l1]:=q[i];
     91         inc(l1);
     92       end
     93       else begin
     94         a[l2]:=q[i];
     95         inc(l2);
     96       end;
     97 
     98     for i:=l to r do
     99       q[i]:=a[i];
    100     cdq(l,m);
    101     cdq(m+1,r);
    102   end;
    103 
    104 begin
    105   readln(pre,t);
    106   while true do
    107   begin
    108     read(ch);
    109     if ch=3 then break;
    110     if ch=1 then
    111     begin
    112       inc(m);
    113       q[m].ch:=m;
    114       readln(q[m].x,q[m].y,q[m].w);
    115       q[m].op:=-2;
    116     end
    117     else begin
    118       inc(n); inc(m);
    119       readln(x,y,x1,y1);
    120       q[m].w:=n; q[m].ch:=m; q[m].x:=x1; q[m].y:=y1; q[m].op:=1;
    121       inc(m);
    122       q[m].w:=n; q[m].ch:=m; q[m].x:=x-1; q[m].y:=y1; q[m].op:=-1;
    123       inc(m);
    124       q[m].w:=n; q[m].ch:=m; q[m].x:=x1; q[m].y:=y-1; q[m].op:=-1;
    125       inc(m);
    126       q[m].w:=n; q[m].ch:=m; q[m].x:=x-1; q[m].y:=y-1; q[m].op:=1;
    127     end;
    128   end;
    129   sort(1,m);
    130   cdq(1,m);
    131   for i:=1 to n do
    132     writeln(ans[i]);
    133 end.
    View Code
  • 相关阅读:
    Hyper-V自定义专用网络网段
    mongodb导入,导出实例
    kafka介绍二 快速开始
    常用代理IP服务商
    kafka介绍一
    链接汇总
    心态,决定你的人生
    hibernate入门(三)hibernate的三种状态解析
    hibernate入门(二)一级缓存和三种状态解析
    css动画之颤动的动画
  • 原文地址:https://www.cnblogs.com/phile/p/4472948.html
Copyright © 2011-2022 走看看