zoukankan      html  css  js  c++  java
  • [HIHO1555] 四次方根(递推,容斥,矩阵快速幂)

    题目链接:http://hihocoder.com/problemset/problem/1555

    首先要知道一元四次方程根与系数的关系:

    设x^4+ax^3+bx²+cx+d=0的四个根是x1,x2,x3,x4,则
    x1+x2+x3+x4=﹣a
    x1x2+x1x3+x1x4+x2x3+x2x4+x3x4=b
    x1x2x3+x1x2x4+x1x3x4+x2x3x4=﹣c
    x1x2x3x4=d

    设f(n)=x1^n+x2^n+x3^n+x4^n。

    容斥一下就能找到一个递推关系:

    f(n)=(x1+x2+x3+x4)*f(n-1)-(x1x2+x1x3+x1x4+x2x3+x2x4+x3x4)*f(n-2)+(x1x2x3+x1x2x4+x2x3x4)*f(n-3)-(x1x2x3x4)*(fn-4)。

    整理得:f(n)=-af(n-1)-bf(n-2)-cf(n-3)-df(n-4)。

    初始值是这样的:显然f(0)=4,f(1)=-a,f(2)可以由f(1)的结果推过来,展开(x1+x2+x3+x4)^2后,使用上述关系,把f(2)以外的式子减掉,可以得f(2)=a*a-2*b,同理f(3)=f(1)*f(2)+a*b-3*c。

    构造四阶矩阵:

    -a -b -c -d
     1  0  0  0
     0  1  0  0
     0  0  1  0

    负数模运算要注意,先+mod变成正数。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long LL;
     5 const LL mod = 1e9+7;
     6 const int maxn = 100;
     7 
     8 typedef struct Matrix {
     9     LL m[maxn][maxn];
    10     int r, c;
    11     Matrix(){
    12         r = c = 0;
    13         memset(m, 0, sizeof(m));
    14     } 
    15 } Matrix;
    16 Matrix mul(Matrix m1, Matrix m2, LL mod) {
    17     Matrix ans = Matrix();
    18     ans.r = m1.r; ans.c = m2.c;
    19     for(int i = 1; i <= m1.r; i++) {
    20         for(int j = 1; j <= m2.r; j++) {
    21             for(int k = 1; k <= m2.c; k++) {
    22                 if(m2.m[j][k] == 0) continue;
    23                 ans.m[i][k] = (ans.m[i][k] + (m1.m[i][j] * m2.m[j][k]) % mod) % mod;
    24             }
    25         }
    26     }
    27     return ans;
    28 }
    29 Matrix quickmul(Matrix m, LL n, LL mod) {
    30     Matrix ans = Matrix();
    31     for(int i = 1; i <= m.r; i++) ans.m[i][i] = 1;
    32     ans.r = m.r;
    33     ans.c = m.c;
    34     while(n) {
    35         if(n & 1) ans = mul(m, ans, mod);
    36         m = mul(m, m, mod);
    37         n >>= 1;
    38     }
    39     return ans;
    40 }
    41 
    42 LL n,a,b,c,d;
    43 
    44 signed main() {
    45     // freopen("in", "r", stdin);
    46     int T;
    47     LL f[11];
    48     scanf("%d", &T);
    49     while(T--) {
    50         scanf("%lld%lld%lld%lld%lld",&n,&a,&b,&c,&d);
    51         f[0] = 4LL;
    52         f[1]=-a;
    53         f[2]=-2LL*b%mod-1LL*a*f[1]%mod;
    54         f[3]=-3LL*c%mod-1LL*b*f[1]%mod-1LL*a*f[2]%mod;
    55         f[4]=-4LL*d%mod-1LL*c*f[1]%mod-1LL*b*f[2]%mod-1LL*a*f[3]%mod;
    56         f[1]=(mod+f[1]%mod)%mod;f[2]=(mod+f[2]%mod)%mod;f[3]=(mod+f[3]%mod)%mod;f[4]=(mod+f[4]%mod)%mod;
    57         Matrix p; p.r = p.c = 4;
    58         p.m[1][1] = (-a+mod)%mod; p.m[1][2] = (-b+mod)%mod;
    59         p.m[1][3] = (-c+mod)%mod; p.m[1][4] = (-d+mod)%mod;
    60         p.m[2][1] = 1; p.m[3][2] = 1; p.m[4][3] = 1;
    61         if(n <= 4) {
    62             printf("%lld
    ", f[n]);
    63             continue;
    64         }
    65         p = quickmul(p, n-4, mod);
    66         LL ret = 0;
    67         for(int i = 1; i <= 4; i++) {
    68             ret += p.m[1][i]*f[4-i+1]%mod;
    69             ret %= mod;
    70         }
    71         printf("%lld
    ", ret);
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    Windows环境下Unicode编程总结
    我的CS脚本autoexec.cfg
    完成端口与高性能服务器程序开发[引用]
    调用未知DLL中的导出函数
    兼容Vista 赛门铁克公测新杀毒软件
    I Love You的真正含义
    码根码
    木马经典十大藏身地点大搜查
    Windows调试器及不同平台符号包下载地址(收集)
    “千般路”与“磨豆腐”
  • 原文地址:https://www.cnblogs.com/kirai/p/7403834.html
Copyright © 2011-2022 走看看