zoukankan      html  css  js  c++  java
  • codeforces 514E-Darth Vader and Tree

    题意:有个无限大的有根树,每个节点都有N个孩子,每个孩子距离父亲节点的距离为di.求距离根节点距离<=x的节点个数.

    思路:注意观察数据范围,每一个d[i]均小于等于100所以我们可以设dp[i]表示距离原点i的点的个数,sum[i]表示总和,最后求sum[x]即可。

    状态转移方程

    1 for(int i=1;i<=100;i++)
    2     {
    3         for(int j=1;j<=i;j++)
    4         {
    5             dp[i]=(dp[i]+dp[i-j]*cnt[j])%MOD;
    6         }
    7         sum[i]=(sum[i-1]+dp[i])%MOD;
    8     }

    但是因为x太大,而且dp[n+1]是每个dp[i]*cnt[n+1-i],令N=100,保存n+1前100个数,并用第101列更新sum,用矩阵快速幂求解即可。(C是单位矩阵!!!)

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 const ll MOD=(ll)1e9+7;
      5 
      6 struct matrix
      7 {
      8     ll x,y;
      9     ll a[112][112];
     10     matrix(){
     11     };
     12     matrix(ll xx,ll yy):x(xx),y(yy)
     13     {
     14         memset(a,0,sizeof(a));
     15     }
     16 }Base;
     17 
     18 matrix mul (matrix A,matrix B)
     19 {
     20     matrix C(A.x,B.y);
     21     for(int i=1;i<=A.x;i++)
     22     {
     23         for(int j=1;j<=B.y;j++)
     24         {
     25             for(int k=1;k<=B.x;k++)
     26             {
     27                 C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j])%MOD;
     28             }
     29         }
     30     }
     31     return C;
     32 }
     33 
     34 ll n,x,cnt[120],sum[120],dp[120];
     35 void init()
     36 {
     37     memset(cnt,0,sizeof(cnt));
     38     scanf("%lld%lld",&n,&x);
     39     for(int i=1;i<=n;i++)
     40     {
     41         int p;
     42         scanf("%d",&p);
     43         cnt[p]++;
     44     }
     45     memset(sum,0,sizeof(sum));
     46     dp[0]=1; sum[0]=1;
     47     for(int i=1;i<=100;i++)
     48     {
     49         for(int j=1;j<=i;j++)
     50         {
     51             dp[i]=(dp[i]+dp[i-j]*cnt[j])%MOD;
     52         }
     53         sum[i]=(sum[i-1]+dp[i])%MOD;
     54     }
     55     
     56     Base.x=101; Base.y=101;
     57     //123...97 98 99  100 101(ans)
     58     
     59     //000...000 len[100] len[100]
     60     //100...000 len[99] len[99]
     61     //010...000 len[98] len[98]
     62     //.........................
     63     //000...001 len[1] len[1]
     64     //000...000 0        1
     65     for(int i=1;i<=99;i++)
     66     {
     67         Base.a[i+1][i]=1;
     68         Base.a[i][100]=cnt[101-i];
     69         Base.a[i][101]=cnt[101-i];
     70     }
     71     Base.a[100][100]=Base.a[100][101]=cnt[1];
     72     Base.a[101][101]=1;
     73 }
     74 
     75 matrix qpow (matrix Base,ll b)
     76 {
     77     matrix C(Base.x,Base.y);
     78     for(int i=1;i<=101;i++) C.a[i][i]=1;//danweijuzhen
     79     while(b)
     80     {
     81         if(b%2==1) C=mul(C,Base);
     82         b/=2;
     83         Base=mul(Base,Base);
     84     }
     85     return C;
     86 }
     87 
     88 int main()
     89 {
     90     init();
     91     matrix A(1,101);
     92     for(int i=1;i<=100;i++) A.a[1][i]=dp[i];
     93     A.a[1][101]=sum[100];
     94     if(x<=100)
     95     {
     96         printf("%lld
    ",sum[x]);
     97         return 0;
     98     }
     99     A=mul(A,qpow(Base,x-100));
    100     printf("%lld
    ",A.a[1][101]%MOD);
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    MySQL Backup mysqldump 常用选项与主要用法--转发
    openssl 之RSA加密
    Windows 之Dll/lib导出
    缓存雪崩、击穿、穿透
    时间复杂度
    分布式事务
    mysql主从复制与读写分离
    什么是消息队列?
    微服务架构演化
    高并发问题常规思路
  • 原文地址:https://www.cnblogs.com/Forever-666/p/10925800.html
Copyright © 2011-2022 走看看