zoukankan      html  css  js  c++  java
  • 【以前的空间】可持久化题目

    可持久化并查集
    3673:可持久化并查集 by zky

    3674: 可持久化并查集加强版

    const
    
      maxn1=10000100;
    
      maxn2=500000;
    
    var
    
      lson,rson,fa,deep:array[0..maxn1]of longint;
    
      root:array[0..maxn2]of longint;
    
      tot,n,m:longint;
    
    
    
    procedure swap(var x,y:longint);
    
    var
    
      i:longint;
    
    begin
    
      i:=x;
    
      x:=y;
    
      y:=i;
    
    end; 
    
    
    
    procedure build(var x:longint;ll,rr:longint);
    
    var
    
      mid:longint;
    
    begin
    
      inc(tot);
    
      x:=tot;
    
      if ll=rr then begin
    
        fa[x]:=ll;
    
        exit;
    
      end;
    
      mid:=(ll+rr)>>1;
    
      build(lson[x],ll,mid);
    
      build(rson[x],mid+1,rr);
    
    end;
    
    
    
    procedure change(x,y,ll,rr,old:longint;var new:longint);
    
    var
    
      mid:longint;
    
    begin
    
      inc(tot);
    
      new:=tot;
    
      if ll=rr then begin
    
        fa[new]:=y;
    
        exit;
    
      end;
    
      mid:=(ll+rr)>>1;
    
      if x<=mid then begin
    
        rson[new]:=rson[old];
    
        change(x,y,ll,mid,lson[old],lson[new]);
    
      end
    
      else begin
    
        lson[new]:=lson[old];
    
        change(x,y,mid+1,rr,rson[old],rson[new]);
    
      end;
    
    end;
    
    
    
    function query(x,y,ll,rr:longint):longint;
    
    var
    
      mid:longint;
    
    begin
    
      if ll=rr then exit(x);
    
      mid:=(ll+rr)>>1;
    
      if y<=mid then exit(query(lson[x],y,ll,mid))
    
        else exit(query(rson[x],y,mid+1,rr))
    
    end;
    
    
    
    procedure add(x,y,ll,rr:longint);
    
    var
    
      mid:longint;
    
    begin
    
      if ll=rr then begin
    
        inc(deep[x]);
    
        exit;
    
      end;
    
      mid:=(ll+rr)>>1;
    
      if y<=mid then add(lson[x],y,ll,mid)
    
        else add(rson[x],y,mid+1,rr);
    
    end;
    
    
    
    function getfa(x,y:longint):longint;
    
    var
    
      ans:longint;
    
    begin
    
      ans:=query(x,y,1,n);
    
      if y=fa[ans] then exit(ans)
    
        else exit(getfa(x,fa[ans]))
    
    end;
    
    
    
    procedure into;
    
    begin
    
      tot:=0;
    
      readln(n,m);
    
      build(root[0],1,n);
    
    end;
    
    
    
    procedure work;
    
    var
    
      i,j,x,y,last:longint;
    
    begin
    
      last:=0;
    
      for i:=1 to m do begin
    
        read(j);
    
        root[i]:=root[i-1];
    
        case j of
    
          1:begin
    
              readln(x,y);
    
              x:=x xor last;
    
              y:=y xor last;
    
              x:=getfa(root[i],x);
    
              y:=getfa(root[i],y);
    
              if fa[x]<>fa[y] then begin
    
                if deep[x]>deep[y] then swap(x,y);
    
                change(fa[x],fa[y],1,n,root[i],root[i]);
    
                if deep[x]=deep[y] then add(root[i],fa[y],1,n);
    
              end;
    
          end;
    
          2:begin
    
              readln(x);
    
              x:=x xor last;
    
              root[i]:=root[x];
    
          end;
    
          3:begin
    
              readln(x,y);
    
              x:=x xor last;
    
              y:=y xor last;
    
              x:=getfa(root[i],x);
    
              y:=getfa(root[i],y);
    
              if fa[x]<>fa[y] then last:=0
    
                else last:=1;
    
              writeln(last);
    
          end;
    
        end;
    
      end;
    
    end;
    
    
    
    begin
    
      into;
    
      work;
    
    end.
    View Code

    【BZOJ3261】 最大异或和(可持久化trie)

    然后无聊写了非递归,结果一点都不快,不开心

    (算是uscao 6.1.3 cowxor 升级版?!)

    const
    
      maxn1=13000010;
    
      maxn2=601000;
    
      maxd=24;
    
    var
    
      sum:array[0..maxn1]of longint;
    
      son:array[0..maxn1,0..1]of longint;
    
      num1,num2,root:array[0..maxn2]of longint;
    
      tot,n,m:longint;
    
    
    
    
    
    function addson(var x:longint):longint;
    
    begin
    
      inc(tot);
    
      x:=tot;
    
      exit(x);
    
    end;
    
    
    
    procedure insert(x,old:longint;var new:longint);
    
    var
    
      i,j,k:longint;
    
    begin
    
      addson(new);
    
      k:=new;
    
      for i:=maxd downto -1 do begin
    
        sum[new]:=sum[old]+1;
    
        if i=-1 then break; //i一定得到-1!!
    
        son[new]:=son[old];
    
        j:=(x>>i) and 1;
    
        old:=son[old][j];
    
        new:=addson(son[new][j]);
    
      end;
    
      new:=k;
    
    end;
    
    
    
    procedure query(x,lr,rr:longint);
    
    var
    
      i,j,ans:longint;
    
    begin
    
      ans:=0;
    
      for i:=maxd downto 0 do begin
    
        j:=(x>>i) and 1;
    
        if sum[son[rr][j xor 1]]-sum[son[lr][j xor 1]]>0 then begin
    
          ans:=ans+1<<i;
    
          lr:=son[lr][j xor 1];
    
          rr:=son[rr][j xor 1];
    
        end
    
        else begin
    
          lr:=son[lr][j];
    
          rr:=son[rr][j];
    
        end;
    
      end;
    
      writeln(ans);
    
    end;
    
    
    
    procedure into;
    
    var
    
      i:longint;
    
    begin
    
      readln(n,m);
    
      inc(n);
    
      tot:=0;
    
      insert(0,root[0],root[1]);
    
      for i:=2 to n do begin
    
        read(num1[i]);
    
        num2[i]:=num2[i-1] xor num1[i];
    
        insert(num2[i],root[i-1],root[i]);
    
      end;
    
      readln;
    
    end;
    
    
    
    procedure work;
    
    var
    
      i,l,r,x:longint;
    
      ch:char;
    
    begin
    
      for i:=1 to m do begin
    
        read(ch);
    
        case ch of
    
          'A':begin
    
                inc(n);
    
                readln(num1[n]);
    
                num2[n]:=num2[n-1] xor num1[n];
    
                insert(num2[n],root[n-1],root[n]);
    
          end;
    
          'Q':begin
    
                readln(l,r,x);
    
                query(x xor num2[n],root[l-1],root[r]);
    
          end;
    
        end;
    
      end;
    
    end;
    
    
    
    
    
    begin
    
      into;
    
      work;
    
    end.
    View Code

     

    【BZOJ3166】[Heoi2013]Alo (可持久化trie)

    orz一下大神的题解

    http://blog.csdn.net/oceanlight/article/details/13783591

    http://hi.baidu.com/ecoecstasy/item/2b4f93dbeeb0f42438f6f748

    方法是枚举每个数是次大值时,然后找出这个数作为次大值时的最大区间【l,r】,在【l,r】中算出答案。

    问题一:如何求出这个数作为次大值的区间

       很显然这个数如果作为次大值,有两个区间,令l1[i]=在i前比num[i]大的第一个数,l2[i]=在i前比num[i]大的第二个数,r1[i]=在i后比num[i]大的第一个数,r2[i]=在i后比num[i]大的第二个数,那么i是区间内的次大值有两个区间,一个是[l1[i]+1,r2[i]-1],另一个是[l2[i]+1,r1[i]-1]。

       注意到l1[i]与l2[i]有很大关系,考虑在l1[i]基础上求l2[i]

       法一,快排后解决

         每个数按大小先排好,a[i]为这个数的值,b[i]为在原数列中的位置。

         初始化每个值的l1[i]=i-1,r1[i]=i+1,然后按值从大到小处理,

         l2[b[i]]=l1[l1[b[i]]];

         r2[b[i]]=r1[r1[b[i]]];

         然后改l1[b[i]]的r1为r1[b[i]],改r1[b[i]]的l1为l1[b[i]],画图试一下,就是原序列中小的数的l2,r2都算出来,那么前面指到后面,后面指到前面……

       法二:单调队列

         单调队列求在它前面比它大的数应该很简单吧(就是不断出队指到队尾的数比要加进的数大,此时队尾的数就是在它前面比它大的第一个数,即),然后就是找l1[i]前比它大的数,这时由于i前所有数的l1[i]以求出,就直接从j=l1[i]-1开始找l1[j]比i大的数,就是l2[i]了

    问题二,求解

    显然直接枚举就行了

    枚举每个数作为次大值时在两个区间内(一个是[l1[i]+1,r2[i]-1],另一个是[l2[i]+1,r1[i]-1]。)所能得到的最大值……然后发现两个区间是重叠的,而且……重叠对结果没有影响(因为是在区间内取一个数),就直接查询区间[l2[i]+1,r2[i]-1],用可持久话trie解决就行了!

    (特殊处理两种情况,一是在它之前没有比它大的数,显然此时就查[0,r2[i]-1],一是在它之后没有比它大的数,显然就查[l2[i]+1,n]。)

    果然还是太弱,本来想对问题一用bit的……真是个蒟蒻,然后因为trie进度又被甩了几条街

    const
    
      maxn1=8000000;
    
      maxn2=300000;
    
      maxd=30;
    
    
    
    var
    
      sum:array[0..maxn1]of longint;
    
      son:array[0..maxn1,0..1]of longint;
    
      num,l1,l2,r1,r2,root,p:array[0..maxn2]of longint;
    
      n,tot,mm:longint;
    
    
    
    function max(x,y:longint):longint;
    
    begin
    
      if x<y then exit(y);
    
      exit(x);
    
    end;
    
    
    
    function addson(var x:longint):longint;
    
    begin
    
      inc(tot);
    
      x:=tot;
    
      exit(x);
    
    end;
    
    
    
    procedure insert(x,old,new:longint);
    
    var
    
      i,j:longint;
    
    begin
    
      for i:=maxd downto -1 do begin
    
        sum[new]:=sum[old]+1;
    
        if i=-1 then break;
    
        son[new]:=son[old];
    
        j:=(x>>i) and 1;
    
        old:=son[old][j];
    
        new:=addson(son[new][j]);
    
      end;
    
    end;
    
    
    
    function query(ll,rr,x:longint):longint;
    
    var
    
      i,j,ans:longint;
    
    begin
    
      if ll>=rr then exit(0);
    
      ll:=root[ll];
    
      rr:=root[rr];
    
      ans:=0;
    
      for i:=maxd downto 0 do begin
    
        j:=(x>>i) and 1;
    
        if sum[son[rr][j xor 1]]-sum[son[ll][j xor 1]]>0 then begin
    
          ans:=ans+1<<i;
    
          j:=j xor 1;
    
        end;
    
        ll:=son[ll][j];
    
        rr:=son[rr][j];
    
      end;
    
      exit(ans);
    
    end;
    
    
    
    procedure into;
    
    var
    
      i,j,tail:longint;
    
    begin
    
      insert(0,root[0],addson(root[0]));
    
      readln(n);
    
      mm:=0;
    
      for i:=1 to n do begin
    
        read(num[i]);
    
        if num[i]>mm then mm:=num[i];
    
        insert(num[i],root[i-1],addson(root[i]));
    
      end;
    
      tail:=0;
    
      l1[0]:=0;
    
      for i:=1 to n do begin
    
        while (tail>0) and (num[i]>=num[p[tail]]) do dec(tail);
    
        if tail=0 then l1[i]:=0
    
          else l1[i]:=p[tail];
    
        inc(tail);
    
        p[tail]:=i;
    
        l2[i]:=0;
    
        j:=l1[i]-1;
    
        while j>0 do
    
          if num[j]>num[i] then begin
    
            l2[i]:=j;
    
            break;
    
          end
    
          else j:=l1[j];
    
      end;
    
      tail:=0;
    
      for i:=n downto 1 do begin
    
        while (tail>0) and (num[i]>=num[p[tail]]) do dec(tail);
    
        if tail=0 then r1[i]:=n+1
    
          else r1[i]:=p[tail];
    
        inc(tail);
    
        p[tail]:=i;
    
        if r1[i]=n+1 then continue;
    
        r2[i]:=n+1;
    
        j:=r1[i]+1;
    
        while j<=n do
    
          if num[j]>num[i] then begin
    
            r2[i]:=j;
    
            break;
    
          end
    
          else j:=r1[j];
    
      end;
    
    end;
    
    
    
    procedure work;
    
    var
    
      i,ans:longint;
    
    begin
    
      ans:=0;
    
      for i:=1 to n do
    
        if num[i]<>mm then begin
    
          if r1[i]>n then r2[i]:=n+1;
    
          ans:=max(ans,query(l2[i],r2[i]-1,num[i]));
    
        end;
    
      writeln(ans);
    
    end;
    
    
    
    begin
    
      into;
    
      work;
    
    end.
    View Code

    2741: 【FOTILE模拟赛】L (可持久化trie)

    方法类似【BZOJ3261】 最大异或和。

    同样定义一个b[i]数组表示前i个数xor值。

    问题为查询i属于[l,r]中a[i] xor a[i+1] xor ... xor a[j]的最大值。

    然后用b[i]数组后变为b[i-1] xor b[j]的最大值。

    然后如果是j固定的话就是BZOJ3261,可以在用求解,问题是j不固定,j属于[l,r]。于是……分块!

    先预处理出一个dp[i,j]表示第i块块头到j的最大值。

    这样[l,r]询问就可以变为[l,X)[X,r](X为l所在块的下一块块头。

    [l,X)直接暴力求i属于[l,X)中的b[i-1]在区间[l,r]中能取得的xor 最大值。

    [X,r]分块预处理后直接出答案。

    然后就没了。

    然后记得取mod!!!!

    const
    
     maxn1=9000900;
    
     maxn2=50000;
    
     maxd=31;
    
    var
    
      sum:array[0..maxn1]of longint;
    
      son:array[0..maxn1,0..1]of longint;
    
      root,num:array[-1..maxn2]of longint;
    
      dp:array[0..250,0..maxn2]of longint;
    
      n,m,tot,block:longint;
    
     
    
    function calc(x:longint):longint;
    
    begin
    
      if x mod block=0 then exit(x div block)
    
        else exit(x div block+1);
    
    end;
    
     
    
    function max(x,y:longint):longint;
    
    begin
    
      if x<y then exit(y);
    
      exit(x);
    
    end;
    
     
    
    function min(x,y:longint):longint;
    
    begin
    
      if x<y then exit(x);
    
      exit(y);
    
    end;
    
     
    
    function addson(var x:longint):longint;
    
    begin
    
      inc(tot);
    
      x:=tot;
    
      exit(x);
    
    end;
    
     
    
    procedure insert(x,old,new:longint);
    
    var
    
      i,j,k:longint;
    
    begin
    
      for i:=maxd downto -1 do begin
    
        sum[new]:=sum[old]+1;
    
        if i=-1 then break;
    
        son[new]:=son[old];
    
        j:=(x>>i) and 1;
    
        old:=son[old][j];
    
        new:=addson(son[new][j]);
    
      end;
    
    end;
    
     
    
    function query(x,lr,rr:longint):longint;
    
    var
    
      ans,i,j:longint;
    
    begin
    
      ans:=0;
    
      for i:=maxd downto 0 do begin
    
        j:=(x>>i) and 1;
    
        if sum[son[rr][j xor 1]]-sum[son[lr][j xor 1]]>0 then begin
    
          ans:=ans+1<<i;
    
          j:=j xor 1;
    
        end;
    
        rr:=son[rr][j];
    
        lr:=son[lr][j];
    
      end;
    
      exit(ans);
    
    end;
    
     
    
    function getans(ll,rr:longint):longint;
    
    var
    
      l,r,ans,i:longint;
    
    begin
    
      l:=calc(ll);
    
      if l*block<rr
    
        then ans:=dp[l+1,rr]
    
        else ans:=0;
    
      for i:=ll to min(l*block,rr) do
    
        ans:=max(ans,query(num[i],root[ll],root[rr]));
    
    end;
    
     
    
    procedure into;
    
    var
    
      i,j:longint;
    
    begin
    
      read(n,m);
    
      j:=0;
    
      insert(0,root[-1],addson(root[0]));
    
      num[0]:=0;
    
      for i:=1 to n do begin
    
        read(j);
    
        num[i]:=num[i-1] xor j;
    
        insert(num[i],root[i-1],addson(root[i]));
    
      end;
    
      block:=trunc(sqrt(n));
    
      for i:=1 to n do
    
        for j:=1 to calc(i) do
    
          dp[j,i]:=max(dp[j,i-1],query(num[i],root[(j-1)*block-1],root[i-1]));
    
    end;
    
     
    
    procedure work;
    
    var
    
      last,j,k,l:longint;
    
    begin
    
      last:=0;
    
      while m>0 do begin
    
        dec(m);
    
        readln(j,k);
    
        j:=(j+last mod n) mod n+1; //千万记得取mod
    
        k:=(k+last mod n) mod n+1;
    
        last:=getans(min(j,k)-1,max(j,k));
    
        writeln(last);
    
      end;
    
    end;
    
     
    
     
    
    begin
    
      into;
    
      work;
    
    end.
    View Code
  • 相关阅读:
    下载安装ActiveMQ(消息队列)
    互联网项目架构之基于服务的分布式架构
    Shell报错bash^M /bin/bash^M: bad interpreter: No such file or directory
    rpm参数
    zabbix3.4+grafana5.0.1数据可视化
    Linux下目录栈操作详解
    有惊无险,拯救zabbix网页端
    tomcat7 开启gzip压缩
    欢迎使用CSDN-markdown基本语法
    新项目平台后台测试环境搭建
  • 原文地址:https://www.cnblogs.com/Macaulish/p/6492148.html
Copyright © 2011-2022 走看看