zoukankan      html  css  js  c++  java
  • [CF718C] Sasha and Array

    18.10.30模拟赛T2。

    CF题目传送门

    洛谷传送门

    模拟赛现场切了这个题......但是这道题有点卡常啊,时限3秒差点没过。

    老师的电脑上能过,自己的机器上过不了......

    我写的东西常数还是太大了QAQ

    题解:

    这道题思路比较简单。

    区间的操作肯定是线段树维护一下。

    要是用线段树修改ai,每次查询的时候还得暴力算fib。

    我们考虑用线段树维护fib(ai)。

    这样查询比较容易了,但是修改就不能直接区间加上一个数了。

    事实上很难仅仅维护一个fib(ai)。

    干脆维护[ fib(ai)  fib(ai-1) ]这个矩阵。

    每次修改的时候乘上转移矩阵的x次幂就好了。

    由于要统计区间和,我们也要维护区间和。

    显然矩阵乘完相加和先加再乘,结果是一样的。

    所以......就再写一个矩阵相加。

    通过这道题发现unsigned long long比long long快很多......

    long long 3.1s的点,unsigned long long只需要跑2.2s左右。

    而矩阵乘法加个取址也不过就快0.1s。

    所以unsigned这个优化很强啊......

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 typedef long long ll;
      6 const int mod=1000000007;
      7 
      8 struct matrix
      9 {
     10     ll a[2][2];
     11 }bs,unt;
     12 
     13 bool same(matrix &q,matrix &w)
     14 {
     15     if(q.a[0][0]!=w.a[0][0])return 0;
     16     if(q.a[0][1]!=w.a[0][1])return 0;
     17     if(q.a[1][0]!=w.a[1][0])return 0;
     18     if(q.a[1][1]!=w.a[1][1])return 0;
     19     return 1;
     20 }
     21 
     22 matrix mul(matrix &q,matrix &w)
     23 {
     24     matrix rt;
     25     for(int i=0;i<=1;i++)
     26     {
     27         for(int j=0;j<=1;j++)
     28         {
     29             rt.a[i][j]=0;
     30             for(int k=0;k<=1;k++)
     31                 rt.a[i][j]=(rt.a[i][j]+q.a[i][k]*w.a[k][j]%mod)%mod;
     32         }
     33     }
     34     return rt;
     35 }
     36 
     37 matrix add(matrix &ret,matrix &q,matrix &w)
     38 {
     39     for(int i=0;i<=1;i++)
     40         for(int j=0;j<=1;j++)
     41             ret.a[i][j]=(q.a[i][j]+w.a[i][j])%mod;
     42 }
     43 
     44 matrix ksm(matrix b,int p)
     45 {
     46     if(!p)return unt;
     47     matrix rt=b;
     48     p--;
     49     while(p)
     50     {
     51         if(p&1)rt=mul(rt,b);
     52         b=mul(b,b);
     53         p>>=1;
     54     }
     55     return rt;
     56 }
     57 
     58 int n,m;
     59 int st[100005];
     60 int lb[400005],rb[400005];
     61 matrix sum[400005],lz[400005];
     62 
     63 void pushup(int p)
     64 {
     65     add(sum[p],sum[p<<1],sum[p<<1|1]);
     66 }
     67 
     68 void build(int p,int l,int r)
     69 {
     70     lb[p]=l,rb[p]=r;
     71     lz[p]=unt;
     72     if(l==r)
     73     {
     74         sum[p]=ksm(bs,st[l]-1);
     75         return;
     76     }
     77     int mid=(l+r)>>1;
     78     build(p<<1,l,mid);
     79     build(p<<1|1,mid+1,r);
     80     pushup(p);
     81 }
     82 
     83 void pushdown(int p)
     84 {
     85     if(same(unt,lz[p]))return;
     86     sum[p<<1]=mul(sum[p<<1],lz[p]);
     87     sum[p<<1|1]=mul(sum[p<<1|1],lz[p]);
     88     lz[p<<1]=mul(lz[p<<1],lz[p]);
     89     lz[p<<1|1]=mul(lz[p<<1|1],lz[p]);
     90     lz[p]=unt;
     91 }
     92 
     93 void mul(int p,int l,int r,matrix &v)
     94 {
     95     if(l>r)return;
     96     if(lb[p]>=l&&rb[p]<=r)
     97     {
     98         sum[p]=mul(sum[p],v);
     99         lz[p]=mul(lz[p],v);
    100         return;
    101     }
    102     pushdown(p);
    103     int mid=(lb[p]+rb[p])>>1;
    104     if(l<=mid)mul(p<<1,l,r,v);
    105     if(r>mid)mul(p<<1|1,l,r,v);
    106     pushup(p);
    107 }
    108 
    109 ll ask(int p,int l,int r)
    110 {
    111     if(l>r)return 0;
    112     if(lb[p]>=l&&rb[p]<=r)
    113     {
    114         return sum[p].a[0][0];
    115     }
    116     ll ret=0;
    117     pushdown(p);
    118     int mid=(lb[p]+rb[p])>>1;
    119     if(l<=mid)ret+=ask(p<<1,l,r);
    120     if(r>mid)ret+=ask(p<<1|1,l,r);
    121     ret=ret%mod;
    122     return ret;
    123 }
    124 
    125 int read()
    126 {
    127     int ret=0;char cc=getchar();
    128     while(cc<'0'||cc>'9')cc=getchar();
    129     while(cc>='0'&&cc<='9')ret=ret*10+cc-'0',cc=getchar();
    130     return ret;
    131 }
    132 
    133 int main()
    134 {
    135     bs.a[0][0]=1;
    136     bs.a[0][1]=1;
    137     bs.a[1][0]=1;
    138     bs.a[1][1]=0;
    139     unt.a[0][0]=1;
    140     unt.a[0][1]=0;
    141     unt.a[1][0]=0;
    142     unt.a[1][1]=1;
    143     scanf("%d%d",&n,&m);
    144     for(int i=1;i<=n;i++)scanf("%d",&st[i]);
    145     build(1,1,n);
    146     for(int i=1;i<=m;i++)
    147     {
    148         int op;
    149         scanf("%d",&op);
    150         if(op==1)
    151         {
    152             int l=read(),r=read(),x=read();
    153             //scanf("%d%d%d",&l,&r,&x);
    154             matrix tmp=ksm(bs,x);
    155             mul(1,l,r,tmp);
    156         }
    157         if(op==2)
    158         {
    159             int l=read(),r=read();
    160             //scanf("%d%d",&l,&r);
    161             ll ans=ask(1,l,r);
    162             printf("%I64d
    ",ans);
    163         }
    164     }
    165     return 0;
    166 }
    Code
  • 相关阅读:
    基于Asp.Net webApi owin oauth2的实现
    动态赋值
    C#生成二维码
    深度学习中反卷积层(转置卷积)引起的棋盘格噪声
    batch normalization 批归一化 --- 一个硬币的两面
    FFMPEG常用命令-格式转换-持续更新中
    [译]CRF和QP的区别
    读懂NCHW和NHWC
    [译]GPUView
    有一次接口设计
  • 原文地址:https://www.cnblogs.com/eternhope/p/9877868.html
Copyright © 2011-2022 走看看