zoukankan      html  css  js  c++  java
  • bzoj1494: [NOI2007]生成树计数

    传送门

    被自己的码力低哭了。

    为什么现在随便写个什么一百出头行的并不难写的代码就调一晚上。我大概是个智障吧。

    人类进化还不完全的时候的做法:

    状压最后k个点的联通状态,矩阵转移,快速幂优化即可。

      1 //Achen
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<vector>
      7 #include<cstdio>
      8 #include<queue>
      9 #include<cmath>
     10 #include<set>
     11 #include<map>
     12 #define Formylove return 0
     13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     15 const int p=65521;
     16 typedef long long LL;
     17 typedef double db;
     18 using namespace std;
     19 int k,power[10],zt[10007],S[60];
     20 LL n;
     21 
     22 template<typename T>void read(T &x)  {
     23     char ch=getchar(); x=0; T f=1;
     24     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     25     if(ch=='-') f=-1,ch=getchar();
     26     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     27 }
     28 
     29 int e[12][2],fa[12],bl[12],tot,ec;
     30 int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); }
     31 
     32 LL f[60];
     33 struct jz {
     34     LL a[60][60];
     35     friend jz operator *(const jz&A,const jz&B) {
     36         jz rs;
     37         For(i,1,tot) For(j,1,tot) {
     38             rs.a[i][j]=0;
     39             For(k,1,tot) 
     40                 (rs.a[i][j]+=A.a[i][k]*B.a[k][j]%p)%=p; 
     41         }
     42         return rs;
     43     }
     44 }bs,rs; 
     45 
     46 void jzksm(LL b) {
     47     For(i,1,tot) For(j,1,tot) 
     48         if(i==j) rs.a[i][j]=1; 
     49         else rs.a[i][j]=0;
     50     while(b) {
     51         if(b&1) rs=rs*bs;
     52         bs=bs*bs;
     53         b>>=1;
     54     }
     55 }
     56 
     57 int ansst;
     58 void find_begin() {
     59     For(i,1,k) For(j,i+1,k) {
     60         e[++ec][0]=i;
     61         e[ec][1]=j;
     62     }
     63     int up=(1<<ec)-1;
     64     For(s,0,up) {
     65         int fl=0;
     66         For(i,1,k) fa[i]=i;
     67         For(i,0,ec) if(s&(1<<(i-1))) {
     68             int u=e[i][0],v=e[i][1];
     69             int x=find(u),y=find(v);
     70             if(x>y) swap(x,y);
     71             if(find(u)==find(v)) { fl=1; break; }
     72             fa[y]=x;
     73         }
     74         if(fl) continue;
     75         int id=0,now=0;
     76         For(i,1,k) {
     77             if(find(i)==i) bl[i]=id++;
     78             else bl[i]=bl[find(i)];
     79             now=now+bl[i]*power[i-1];
     80         }
     81         if(!zt[now]) { zt[now]=++tot; S[tot]=now; }
     82         f[zt[now]]++;
     83         if(now==0) 
     84             ansst=zt[now];
     85     }
     86 }
     87 
     88 int nowbl[12],tbl[12];
     89 void find_tans() {
     90     int up=(1<<k)-1;
     91     For(ss,1,tot) {
     92         int now=S[ss],fl=0;
     93         For(i,1,k) {
     94             bl[i]=now%k; tbl[i]=bl[i];
     95             if(i!=1&&bl[i]==bl[1]) fl=1;
     96             now/=k;
     97         }
     98         For(i,0,up) {
     99             if(!fl&&!(i&1)) continue ;
    100             For(j,1,k) bl[j]=tbl[j];
    101             int fll=0;
    102             For(a,1,k) For(b,a+1,k) if((i&(1<<(a-1)))&&(i&(1<<(b-1)))) {
    103                 if(bl[a]==bl[b]) { fll=1; break; }
    104             }
    105             if(fll) continue;
    106             bl[k+1]=k+1; 
    107             int id=0,now=0;
    108             For(a,1,k) if((i&(1<<(a-1)))) {
    109                 For(b,1,k) if(b!=a&&bl[b]==bl[a]) bl[b]=k+1;
    110                 bl[a]=k+1;
    111             }
    112             For(ii,2,k+1) For(j,2,k+1) if(bl[j]==bl[ii]) {
    113                 if(ii==j) nowbl[ii]=id++;
    114                 else nowbl[ii]=nowbl[j];
    115                 now=now+power[ii-2]*nowbl[ii];
    116                 break;
    117             }
    118             bs.a[ss][zt[now]]++;
    119         }
    120     }
    121 }
    122 
    123 //#define ANS
    124 int main() {
    125 #ifdef ANS
    126     freopen("1.in","r",stdin);
    127     freopen("1.out","w",stdout);
    128 #endif
    129     read(k); read(n);
    130     power[0]=1;
    131     For(i,1,k) power[i]=power[i-1]*k;
    132     find_begin();
    133     find_tans();
    134     jzksm(n-k);
    135     LL ans=0;
    136     For(i,1,tot) 
    137         ans=(ans+f[i]*rs.a[i][ansst]%p)%p;
    138     printf("%lld
    ",ans);
    139     Formylove;
    140 }
    View Code

     

    人类进化完全一些之后,可以用BM算法求出递推式,然后矩乘或者多项式取模来做。

    虽然我并不会。

    毕竟我还处于元谋人阶段。

  • 相关阅读:
    UVALive 7509 Dome and Steles
    HDU 5884 Sort
    Gym 101194H Great Cells
    HDU 5451 Best Solver
    HDU 5883 The Best Path
    HDU 5875 Function
    卡特兰数
    UVa 11729 Commando War 突击战
    UVa 11292 The Dragon of Loowater 勇者斗恶龙
    Spark Scala Flink版本对应关系
  • 原文地址:https://www.cnblogs.com/Achenchen/p/9502807.html
Copyright © 2011-2022 走看看