• bzoj4547 小奇的集合


      当序列中最大和次大都是负数的时候,其相加会是一个更小的负数,因此答案为(Σai)+(m1+m2)*k,如果最大是正数次大是负数,那么一直相加直到两个数都为正数,当最大和次大都是正数时,做一下矩阵乘法即可。

      代码

      

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define N 200010
     5 #define P 10000007
     6 using namespace std;
     7 typedef long long ll;
     8 int n,k,i,j,t1,t2;
     9 int a[N];
    10 long long u,v,w,sum;
    11 struct g{
    12     long long v[3][3];
    13     void clear()
    14     {
    15         memset(v,0,sizeof(v));
    16     }
    17 }m,o;
    18 g operator *(g a,g b)
    19 {
    20     g c;c.clear();
    21     int i,j,k;
    22     for (i=0;i<=2;i++)
    23     for (j=0;j<=2;j++)
    24     for (k=0;k<=2;k++)
    25     c.v[i][j]=(c.v[i][j]+a.v[i][k]*b.v[k][j])%P;
    26     return c;
    27 }
    28 g ksm(int x)
    29 {
    30     g ans;
    31     if (x==1)
    32         return o;
    33     ans=ksm(x/2);
    34     ans=ans*ans;
    35     if (x%2)
    36     ans=ans*o;
    37     return ans;
    38 }
    39 int main()
    40 {
    41     a[0]=-2000000000;
    42     scanf("%d%d",&n,&k);
    43     for(i=1;i<=n;i++)
    44     {
    45         scanf("%d",&a[i]);
    46         sum=(sum+a[i])%P;
    47         if (a[i]>a[t1]) t1=i;
    48     }
    49     for (i=1;i<=n;i++)
    50     if ((i!=t1)&&(a[i]>a[t2])) t2=i;
    51     u=a[t1];v=a[t2];
    52     if ((u<=0)&&(v<=0))
    53     {
    54         sum=(sum+(u+v)*k)%P;
    55     }
    56     else
    57     {
    58         while (((u<=0)||(v<=0))&&(k))
    59         {
    60             w=u+v;sum=(w+sum)%P;
    61             u=max(u,v);v=w;k--;
    62         }
    63         if (u>v)
    64         {
    65             w=v;v=u;u=w;
    66         }
    67         o.clear();
    68         o.v[0][1]=o.v[1][0]=o.v[1][1]=1;
    69         o.v[2][0]=o.v[2][1]=o.v[2][2]=1;
    70         if (k) m=ksm(k);
    71         /*
    72         for (i=0;i<=2;i++)
    73         {
    74         for (j=0;j<=2;j++)
    75         printf("%d ",m.v[i][j]);
    76         printf("
    ");
    77         }
    78         */
    79         sum=(sum+u*m.v[2][0]+v*m.v[2][1])%P;
    80     }
    81     printf("%lld
    ",sum);
    82 }
    83 /*
    84 0 1 0
    85 1 1 0
    86 1 1 1
    87 */
  • 相关阅读:
    sed附加命令
    01_Mac下安装homebrew
    02_linux常用指令
    18_Condition条件
    01.IDEA常用快捷键
    17_重入锁ReentrantLock
    秒杀系统架构分析与实战--转载
    16_Queue_利用wait()和notify()编写一个阻塞队列
    15_volatile
    14_synchronized深入
  • 原文地址:https://www.cnblogs.com/fzmh/p/5425261.html
Copyright © 2020-2023  润新知