zoukankan      html  css  js  c++  java
  • HDU5735 : Born Slippy

    考虑DP,设$f[x]$表示最后一个是$x$时的最优解,则$f[x]=max(f[y]+w[x] opt w[y])$,其中$y$是$x$的祖先。

    注意到$w[i]<2^{16}$,那么将数字划分成前$8$位和后$8$位,额外维护一个数组$g[a][b]$表示某个$w[y]$的前$8$位为$a$时,后$8$位$opt b+f[y]$的最大值,那么维护$g$只需要枚举$b$,计算$f$只需要枚举$a$,单次复杂度都是$O(2^8)$。

    对于树的情况只需要保存每次修改,然后在回溯的时候还原即可。

    时间复杂度$O(2^8n)$。

    #include<cstdio>
    #define N 65540
    typedef unsigned int U;
    U T,n,i,x,w[N],g[N],nxt[N],f[256][256],h[N][256],v[256],ans;
    char op[9];
    inline void read(U&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline U opt(U a,U b){
      if(op[0]=='A')return a&b;
      if(op[0]=='O')return a|b;
      return a^b;
    }
    inline void up(U&a,U b){if(a<b)a=b;}
    void dfs(U x){
      U dp=0,A=w[x]>>8,B=w[x]&255,i;
      for(i=0;i<256;i++)if(v[i])up(dp,f[i][B]+(opt(A,i)<<8));
      ans=(1LL*x*(dp+w[x])+ans)%1000000007;
      for(v[A]++,i=0;i<256;i++)h[x][i]=f[A][i],up(f[A][i],opt(B,i)+dp);
      for(i=g[x];i;i=nxt[i])dfs(i);
      for(v[A]--,i=0;i<256;i++)f[A][i]=h[x][i];
    }
    int main(){
      read(T);
      while(T--){
        read(n);scanf("%s",op);
        for(i=1;i<=n;i++)read(w[i]),g[i]=0;
        for(i=2;i<=n;i++)read(x),nxt[i]=g[x],g[x]=i;
        ans=0;
        dfs(1);
        printf("%u
    ",ans);
      }
      return 0;
    }
    

      

  • 相关阅读:
    Linq to DataTable 左连接
    关于值类型和引用类型
    静态页生成
    技术是什么?
    关于GC垃圾回收的原理
    ADO.NET编程之美----数据访问方式(面向连接与面向无连接)
    Unity3d连接SQL Server数据库出现SocketException: 使用了与请求的协议不兼容的地址错误
    JAVA/GUI程序之记事本
    面试常见题
    unsafe
  • 原文地址:https://www.cnblogs.com/clrs97/p/5693738.html
Copyright © 2011-2022 走看看