zoukankan      html  css  js  c++  java
  • bzoj4028

    一眼分块题……

    分块,维护每个块的总的gcd和xor和

    先思考我们应该怎么查询,考虑到gcd是一个神奇的东西,因为它最多变化logX次

    于是我们从前往后扫描每个块,如果一个块内总的gcd是当前扫描的前缀gcd的倍数

    那么,也就意味着这个块里的每个位置所对应的前缀的gcd都等于当前gcd

    因此,我们设当前xor和为nowxor,gcd为nowgcd,partxor为块内某个块前缀xor和

    nowxor xor partxor*nowgcd=x 即 nowxor xor (x/nowgcd)=partxor

    这时候只要查询块内是否存在某个块前缀xor和为nowxor xor (x/nowgcd)即可,这我们可以用hash解决

    如果不是倍数关系,那么我们直接暴力这个块即可,这样的暴力一定不会超过logX次

    至于修改,我们直接暴力重构对应块即可

      1 const mo=124367;
      2 type node=record
      3        po,num,next:longint;
      4      end;
      5 
      6 var e:array[0..6010010] of node;
      7     p:array[0..320,0..mo] of longint;
      8     a,g,b,be:array[0..100010] of longint;
      9     size,t,len,i,j,n,m,x,y:longint;
     10     z:int64;
     11     ch:char;
     12     s:string;
     13 
     14 function gcd(a,b:longint):longint;
     15   begin
     16     if b=0 then exit(a)
     17     else exit(gcd(b,a mod b));
     18   end;
     19 
     20 function min(a,b:longint):longint;
     21   begin
     22     if a>b then exit(b) else exit(a);
     23   end;
     24 
     25 procedure work(x,y,z:longint);
     26   var i,j:longint;
     27   begin
     28     i:=p[x,y mod mo];
     29     while i<>0 do
     30     begin
     31       j:=e[i].po;
     32       if e[i].po=y then
     33       begin
     34         e[i].num:=min(e[i].num,z);
     35         exit;
     36       end;
     37       i:=e[i].next;
     38     end;
     39     inc(len);
     40     e[len].po:=y;
     41     e[len].num:=z;
     42     e[len].next:=p[x,y mod mo];
     43     p[x,y mod mo]:=len;
     44   end;
     45 
     46 procedure del(x,y,z:longint);
     47   var i,j:longint;
     48   begin
     49      i:=p[x,y mod mo];
     50     while i<>0 do
     51     begin
     52       j:=e[i].po;
     53       if e[i].po=y then
     54       begin
     55         if e[i].num=z then e[i].num:=n+1;
     56         exit;
     57       end;
     58       i:=e[i].next;
     59     end;
     60   end;
     61 
     62 function get(x,y:longint):longint;
     63   var i,j:longint;
     64   begin
     65     i:=p[x,y mod mo];
     66     while i<>0 do
     67     begin
     68       j:=e[i].po;
     69       if j=y then exit(e[i].num);
     70       i:=e[i].next;
     71     end;
     72     exit(n+1);
     73   end;
     74 
     75 function ask(x:int64):longint;
     76   var tg,tx,i,j,r,p:longint;
     77   begin
     78     tg:=0; tx:=0;
     79     for i:=1 to size do
     80     begin
     81       tg:=gcd(tg,a[i]);
     82       tx:=tx xor a[i];
     83       if int64(tg)*int64(tx)=x then exit(i);
     84       if x div int64(tg)>1 shl 30 then exit(-1);
     85     end;
     86     for i:=2 to t do
     87     begin
     88       if x div int64(tg)>1 shl 30 then exit(-1);
     89       if i=t then r:=n else r:=i*size;
     90       if g[r] mod tg=0 then
     91       begin
     92         if x mod tg=0 then
     93         begin
     94           p:=get(i,tx xor (x div int64(tg)));
     95           if p<=n then exit(p);
     96         end;
     97         tx:=tx xor b[r];
     98       end
     99       else begin
    100         for j:=(i-1)*size+1 to r do
    101         begin
    102           tg:=gcd(tg,a[j]);
    103           tx:=tx xor a[j];
    104           if int64(tg)*int64(tx)=x then exit(j);
    105           if x div int64(tg)>1 shl 30 then exit(-1);
    106         end;
    107       end;
    108     end;
    109     exit(-1);
    110   end;
    111 
    112 begin
    113   readln(n);
    114   size:=trunc(sqrt(n));
    115   for i:=1 to n do
    116   begin
    117     read(a[i]);
    118     be[i]:=(i-1) div size+1;
    119   end;
    120   t:=n div size;
    121   if n mod size<>0 then inc(t);
    122   for i:=1 to n do
    123   begin
    124     if i mod size=1 then
    125     begin
    126       g[i]:=a[i];
    127       b[i]:=a[i];
    128     end
    129     else begin
    130       b[i]:=b[i-1] xor a[i];
    131       g[i]:=gcd(g[i-1],a[i]);
    132     end;
    133     work(be[i],b[i],i);
    134   end;
    135   readln(m);
    136   for i:=1 to m do
    137   begin
    138     s:='';
    139     read(ch);
    140     while ch<>' ' do
    141     begin
    142       s:=s+ch;
    143       read(ch);
    144     end;
    145     if s[1]='M' then
    146     begin
    147       readln(x,y);
    148       inc(x);
    149       a[x]:=y;
    150       for j:=x to min(size*be[x],n) do
    151       begin
    152         del(be[x],b[j],j);
    153         if j mod size=1 then
    154         begin
    155           b[j]:=a[j];
    156           g[j]:=a[j];
    157         end
    158         else begin
    159           b[j]:=b[j-1] xor a[j];
    160           g[j]:=g[j-1] xor a[j];
    161         end;
    162         work(be[x],b[j],j);
    163       end;
    164     end
    165     else begin
    166       readln(z);
    167       x:=ask(z);
    168       if x=-1 then writeln('no') else writeln(x-1);
    169     end;
    170   end;
    171 end.
    View Code
  • 相关阅读:
    在windows下拆卸Linux就是这么俭朴
    打点Linux下永中Office和桌面殊效的冲突
    Banshee 0.11.4
    ubuntu8.0中文输入法
    RedFlag 6.0 硬盘安置我解
    阅读器和把持体系和用户的IQ
    初试Fedora,最后还是Xubuntu
    VMware中放置Ubuntu后鼠标滚轮标题问题办理
    GNOME 的文件经管器将片面支撑标签式阅读
    ATI显卡开启fedora9的3d后果的一些条记
  • 原文地址:https://www.cnblogs.com/phile/p/4493191.html
Copyright © 2011-2022 走看看