• bzoj 2327 构图暴力判断+独立集个数


    首先我们可以处理出10^6以内的所有的勾股数,如果我们有2*i-1和2*j互质,

     那么A=(2*i-1)*(2*i-1)+(2*i-1)*(2*j),B=2*j*j+(2*i-1)*(2*j)为互质

    勾股数对,且保证所有的互质勾股数对都有这个性质,保证了了我们暴力可以枚举

    所有的勾股数对

    那么我们得到所有的勾股数对后,可以建图,得到一张类似于树的图,然后可能会有

    一些环,但是比较少,一棵树的独立集个数是可以DP求的,那么这样的图可以暴力

    规定每条非树边的两个端点取不取来每次都DP,得出所有情况,这样就行了。

    /**************************************************************
        Problem: 2327
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:3372 ms
        Memory:67608 kb
    ****************************************************************/
     
    //By BLADEVIL
    const
        d39                         =1000000007;
         
    var
        n                           :longint;
        pre, other                  :array[0..2000010] of longint;
        last                        :array[0..1000010] of longint;
        l                           :longint;
        c, cur                      :array[0..1000010] of longint;
        pi                          :array[0..1000010] of longint;
        ans                         :int64;
        tot, sum                    :longint;
        flag                        :array[0..1000010] of boolean;
        b                           :array[0..1000010,0..2] of longint;
        w                           :array[0..1000010,0..2] of int64;
         
         
    function gcd(a,b:longint):longint;
    begin
        if b>a then exit(gcd(b,a)) else
        if b=0 then exit(a) else exit(gcd(b,a mod b));
    end;
     
    procedure connect(x,y:longint);
    begin
        inc(l);
        pre[l]:=last[x];
        last[x]:=l;
        other[l]:=y;
    end;
         
    procedure make;
    var
        i, j                        :longint;
        x, y                        :longint;
    begin
        for i:=1 to 1000 do
            for j:=1 to 1000 do
                if gcd(2*i-1,2*j)=1 then
                begin
                    x:=(2*i-1)*(2*i-1)+(2*i-1)*(2*j);
                    y:=2*j*j+(2*i-1)*(2*j);
                    if (x<=1000000) and (y<=1000000) then
                    begin
                        connect(x,y);
                        connect(y,x);
                    end;
                end;
    end;
     
    procedure init;
    var
        i                           :longint;
        x                           :longint;
         
    begin
        read(n);
        for i:=1 to n do
        begin
            read(x);
            inc(c[x]);
        end;
        pi[0]:=1;
        for i:=1 to n do pi[i]:=pi[i-1]*2 mod d39;
        ans:=1;
    end;
     
    procedure dfs(x,fa:longint);
    var
        q, r, p                     :longint;
        f                           :boolean;
    begin
        flag[x]:=true;
        q:=last[x];
        r:=0;
        while q<>0 do
        begin
            p:=other[q];
            f:=true;
            if c[p]>0 then
            begin
                if not flag[p] then
                    dfs(p,x) else
                if p<>fa then
                begin
                    if x<p then
                    begin
                        inc(tot);
                        b[tot,1]:=x;
                        b[tot,2]:=p;
                    end;
                    if r<>0 then
                        pre[r]:=pre[q] else
                        last[x]:=pre[q];
                    f:=false;
                end;
            end;
            if f then r:=q;
            q:=pre[q];
        end;
    end;
     
    procedure dp(x,fa:longint);
    var
        q, p                        :longint;
     
    begin
        q:=last[x];
        w[x,0]:=1; w[x,1]:=pi[c[x]]-1;
        if cur[x]=1 then w[x,1]:=0;
        if cur[x]=2 then w[x,0]:=0;
        while q<>0 do
        begin
            p:=other[q];
            if (c[p]>0) and (p<>fa) then
            begin
                dp(p,x);
                w[x,0]:=w[x,0]*(w[p,1]+w[p,0]) mod d39;
                w[x,1]:=w[x,1]*w[p,0] mod d39;
            end;
            q:=pre[q];
        end;
    end;
     
    procedure dfs_q(p,num:longint);
    var
        x, y, curx, cury            :longint;
    begin
        if p>tot then
        begin
            dp(num,0);
            sum:=(sum+w[num,0]) mod d39;
            sum:=(sum+w[num,1]) mod d39;
            exit;
        end;
        x:=b[p,1]; y:=b[p,2];
        curx:=cur[x]; cury:=cur[y];
        if (curx<>1) and (cury<>2) then
        begin
            cur[x]:=2;
            cur[y]:=1;
            dfs_q(p+1,num);
            cur[x]:=curx;
            cur[y]:=cury;
        end;
        if (curx<>2) then
        begin
            cur[x]:=1;
            dfs_q(p+1,num);
            cur[x]:=curx;
            cur[y]:=cury;
        end;
          
    end;
     
    procedure main;
    var
        i                           :longint;
    begin
        for i:=1 to 1000000 do
            if (c[i]>0) and (not flag[i]) then
            begin
                tot:=0;
                sum:=0;
                dfs(i,0);
                dfs_q(1,i);
                ans:=ans*sum mod d39;
            end;
        if ans=0 then ans:=d39;
        writeln(ans-1);
    end;
     
    begin
        make;
        init;
        main;
    end.
  • 相关阅读:
    Tomcat生命周期管理与观察者模式
    利于ThreadLocal管理Hibernate Session
    Spring多数据源配置
    MySQL数据库性能优化之硬件瓶颈分析
    浅谈监听器与过滤器
    StringManager与单例模式
    ThreadLocal在spring框架中的作用
    spring中事件机制
    MySQL数据库性能优化之存储引擎选择
    Spring常用的Listener
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3500351.html
Copyright © 2020-2023  润新知