zoukankan      html  css  js  c++  java
  • BZOJ3547 : [ONTAK2010]Matchings

    树形DP

    f[i][0]表示不向下连边的最大匹配数

    f[i][1]表示向下连一条边的最大匹配数

    h[][]表示对应的方案数

    为了防止爆栈用BFS

    为了防止MLE:

    1.数组循环利用,比如存边的数组在存完边后可以用来当dp数组

    2.BFS时判断哪些点已经走过的bool数组改成bitset

    3.能不开数组就不开数组,如前缀积

    4.对于数值不超过n的数组,改成手写的3个unsigned char组合而成的数据类型,可以压缩1/4内存

    5.记录方案的数组只要开int,计算时强制转化成long long

    压了好久内存,终于从77M压到了31M…我发现bool占用空间居然和char是一样的!结构体占用内存是按照里面最大的那种数据类型为基准计算的。

    #include<cstdio>
    #include<bitset>
    typedef long long ll;
    const int N=1500001;
    int n,m,i,j,x,y,g[N],v[N<<1],ed,head,tail,maxv,pre,now,t0,t1;
    std::bitset<N>in;
    struct Num{
      unsigned char a,b,c;
      Num(){a=b=c=0;}
      Num(int x){a=x&255,x>>=8,b=x&255,c=x>>8;}
    }nxt[N<<1],q[N];
    inline int Real(Num x){return (int)x.a|(int)x.b<<8|(int)x.c<<16;}
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline void add(int x,int y){v[++ed]=y;nxt[ed]=Num(g[x]);g[x]=ed;}
    inline ll mul(ll a,ll b){return a*b%m;}
    inline void max(int b){if(maxv<b)maxv=b;}
    int main(){
      read(n);
      for(i=1;i<n;i++)read(x),read(y),add(x,y),add(y,x);
      read(m);
      in[Real(q[head=tail=1]=Num(1))]=1;
      while(head<=tail)for(i=g[x=Real(q[head++])],g[x]=tail+1;i;i=Real(nxt[i]))if(!in[v[i]])in[Real(q[++tail]=Num(v[i]))]=1;
      for(i=1;i<=n*2;i++)nxt[i]=Num(v[i]=0);
      for(i=n;i;i--){
        v[x=Real(q[i])]=1;
        if(g[x]>g[Real(q[i+1])]-1)continue;
        maxv=-N;head=g[x];tail=g[Real(q[i+1])]-1;now=0;
        for(j=head;j<=tail;j++){
          y=Real(q[j]),t0=Real(nxt[y]),t1=Real(nxt[y+n]);
          if(t0>t1){
            now+=t0;
            v[x]=mul(v[x],v[y]);
            v[y+n]=v[y];
            max(0);
          }else if(t0==t1){
            now+=t0;
            v[x]=mul(v[x],v[y]+v[y+n]);
            v[y+n]=(v[y]+v[y+n])%m;
            max(0);
          }else{
            now+=t1;
            v[x]=mul(v[x],v[y+n]);
            max(t0-t1);
          }
          g[y]=v[y+n];
        }
        nxt[x]=Num(now);now+=maxv+1;
        nxt[x+n]=Num(now);
        pre=g[Real(q[tail+1])]=1;
        for(j=tail-1;j>=head;j--)g[Real(q[j])]=mul(g[Real(q[j])],g[Real(q[j+1])]);
        for(j=head;j<=tail;j++){
          y=Real(q[j]),t0=Real(nxt[y]),t1=Real(nxt[y+n]);
          if(t0>=t1){
            if(maxv==0)v[x+n]=(v[x+n]+mul(mul(pre,g[Real(q[j+1])]),v[y]))%m;
          }else{
            if(maxv==t0-t1)v[x+n]=(v[x+n]+mul(mul(pre,g[Real(q[j+1])]),v[y]))%m;
          }
          pre=mul(pre,v[y+n]);
        }
      }
      if(Real(nxt[1])>Real(nxt[1+n]))printf("%d
    %d",Real(nxt[1]),v[1]%m);
      else if(Real(nxt[1])==Real(nxt[1+n]))printf("%d
    %d",Real(nxt[1]),(v[1]+v[1+n])%m);
      else printf("%d
    %d",Real(nxt[1+n]),v[1+n]%m);
      return 0;
    }
    

      

  • 相关阅读:
    宿主机无法访问CentOS7上Jenkins服务的解决办法
    415. Add Strings
    367. Valid Perfect Square
    326. Power of Three
    258. Add Digits
    231. Power of Two
    204. Count Primes
    202. Happy Number
    172. Factorial Trailing Zeroes
    171. Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/clrs97/p/4403208.html
Copyright © 2011-2022 走看看