耗时最长代码合集

CF Sasha and Array(最长注释,长达50行)

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#define num ch-'0'
#define int long long
using namespace std;
typedef long long ll;
const int N=100000+10;
const int mod=1e9+7;
void read(int &x){
    char ch;x=0;
    while(!isdigit(ch=getchar()));
    for(x=num;isdigit(ch=getchar());x=x*10+num);
}
void red(ll &x){
    char ch;x=0;
    while(!isdigit(ch=getchar()));
    for(x=num;isdigit(ch=getchar());x=x*10+num);
}
int n,m;
ll a[N];
struct T{
    ll a[3][3];
    //T() {memset(a,0,sizeof a);laz[1][1]=laz[2][2]=1;}
    void clear(){
        //memset(a,0,sizeof a);
        for(int i=0;i<3;i++)
         for(int j=0;j<3;j++)
          a[i][j]=0;
    }
    void init(){
        a[1][1]=a[2][2]=1;
    }
    bool empty(){
        if(a[1][1]!=1) return 0;
        if(a[1][2]!=0) return 0;
        if(a[2][1]!=0) return 0;
        if(a[2][2]!=1) return 0;
        return 1;
    }
    T operator + (T b){
        T c;c.clear();
        for(int i=1;i<=2;i++)
          for(int j=1;j<=2;j++)
           c.a[i][j]=(c.a[i][j]+b.a[i][j]+a[i][j])%mod;
        return c;
    }/*void print(){
        for(int i=1;i<=2;i++)
        {
            for(int j=1;j<=2;j++)
             cout<<a[i][j]<<" ";
            cout<<endl;
        }
    }*/
    T operator * (T b){
        T c;c.clear();
        for(int i=1;i<=2;i++)
         for(int k=1;k<=2;k++)
          for(int j=1;j<=2;j++)
           c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j])%mod;
        //c.print();
        return c;
    }
   
}t[4*N],laz[4*N],M,B;
T qm(T a,ll y){
    T ret,base;
    ret.clear(),ret.init();
    while(y){
        if(y&1) ret=ret*a;
        a=a*a;
        y>>=1;
    }
    return ret;
}

void pushup(int x){
    t[x]=t[x<<1]+t[x<<1|1];
}
void build(int x,int l,int r){

    laz[x].clear();laz[x].init();
    t[x].clear();
    if(l==r){
        
        t[x]=qm(M,a[l]-1);
        //cout<<l<<" : "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
        //laz[x].print();
        return;
    }
    //laz[x].clear(),laz[x].init();
    int mid=l+r>>1;
    build(x<<1,l,mid);build(x<<1|1,mid+1,r);
    pushup(x);
//    if(l==1&&r==3){
//        cout<<" get "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
//    }
}
void pushdown(int x,int l,int r)
{
    //if(laz[x].empty()) return;
    //if(laz[x].a[1][1]==1&&laz[x].a[2][2]==1&&laz[x].a[2][1]==0&&laz[x].a[1][2]==0) return;
    if(laz[x].empty()) return;
    int ls=(x<<1),rs=(x<<1|1);
    //cout<<" here "<<l<<" "<<r<<endl;
    //if(l==10&&r==14) laz[x].print();
    //cout<<" before "<<endl;
    //t[ls].print(); puts("");t[rs].print();    
   // laz[x].print();
    //cout<<" ans "<<endl;
    //(t[ls]*laz[x]).print();
    t[ls]=t[ls]*laz[x];
    //cout<<" cc "<<endl;cc.print();
    //t[ls]=cc;
    //cout<<"ls:";t[ls].print();
    //T dd=t[rs]*laz[x];
    
    t[rs]=t[rs]*laz[x];
    //t[ls].print(),puts(""),t[rs].print();
    //cout<<"laz "<<laz[rs].pr
    laz[ls]=laz[ls]*laz[x];
    laz[rs]=laz[rs]*laz[x];
    //cout<<" after "<<endl;
   //  puts("");t[rs].print();
   // t[x].laz[1][1]=t[x].laz[2][2]=1;
   laz[x].clear();laz[x].init();
    //t[x].laz=0;
    
}
void update(int x,int l,int r,int L,int R,T c)
{
    //cout<<" ffff "<<l<<" "<<r<<" "<<endl;
    if(L<=l&&r<=R){
    //    cout<<" l and r "<<l<<" "<<r<<endl; 
    //    cout<<" laz1 "<<lz<<" laz2 "<<t[x].laz<<endl;
        t[x]=t[x]*c;
//        cout<<" lazy "<<t[x].laz<<endl;
        //t[x]=t[x]*c;
        laz[x]=laz[x]*c;
        //if(l==1&&r==5) laz[x].print();
        //if(L==8&&R==15) c.print();
        //if(l==10&&r==14) laz[x].print();
    //    if(l==1&&r==3){
    //    cout<<" get222 "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
    //}
        return;
    }
    pushdown(x,l,r);
    int mid=l+r>>1;
    if(L<=mid) update(x<<1,l,mid,L,R,c);
    if(mid<R) update(x<<1|1,mid+1,r,L,R,c);
    pushup(x);
    //if(l==1&&r==3){
    //    cout<<" get222 "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
    //}
}
T query(int x,int l,int r,int L,int R)
{
    //if(L==1&&R==3) cout<<"finding "<<l<<" "<<r<<endl;
    //cout<<" finding "<<l<<" "<<r<<endl;
    //if(l==1&&r==5) laz[x].print();
    if(L<=l&&r<=R){
        
       // if(l==4&&r==5) t[x].print();
        return t[x];
    }
    //cout<<" dfdfdfdfd "<<l<<" "<<r<<endl;
    pushdown(x,l,r);
    //cout<<" fdfdfdf "<<l<<" "<<r<<endl;
    T ret;ret.clear();
    //ret.print();
    int mid=l+r>>1;
    //query(x<<1,l,mid,L,R).print();
    if(L<=mid) ret=ret+query(x<<1,l,mid,L,R);
    if(mid<R) ret=ret+query(x<<1|1,mid+1,r,L,R);
    //cout<<" after "<<l<<" "<<r<<" : "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
    return ret;
}
ll work(int l,int r)
{
    T ret;ret.clear();
    ret=B*query(1,1,n,l,r);
    return ret.a[1][1];
}
signed main()
{
    
    B.clear(),M.clear();
    B.a[1][1]=1;//B.a[1][2]=1;
    M.a[1][1]=M.a[1][2]=M.a[2][1]=1;
    //scanf("%I64d%I64d",&n,&m);
    read(n);read(m);
    for(int i=1;i<=n;i++) 
    red(a[i]);
    //scanf("%I64d",&a[i]);
    build(1,1,n);
    
    int op,l,r;
    ll z;
    while(m--){
       // scanf("%I64d",&op);
       //cout<<"mmmm "<<m<<endl;
       read(op);
        if(op==1){
            //scanf("%I64d%I64d%I64d",&l,&r,&z);
            read(l);read(r);red(z);
            //cout<<" before "<<z<<" "<<endl;
            T k;k=qm(M,z);
            //cout<<" after "<<z<<endl;
            //cout<<k.a[1][1]<<" "<<k.a[1][2]<<" "<<k.a[2][1]<<" "<<k.a[2][2]<<endl;
            update(1,1,n,l,r,k);
        }
        else{
            //scanf("%I64d%I64d",&l,&r);
            read(l);read(r);
            printf("%I64d\n",work(l,r));
        }
    }
    return 0;
}

尤其pushdown满篇注释,其实就错了两点:

1.数组越界了...后果:c++不会告诉你RE,只是不知道在哪里就卡崩了。

现象:莫名的错误;直接赋值出错,间接赋值没错;cout在前可以正确输出,操作一下别的什么东西,cout在后就错了。

死坑死坑死坑的。

2.注释太多,漏了laz之间的下放。。。。

以后,注释没用还是删掉一些为好。

猜你喜欢

转载自www.cnblogs.com/Miracevin/p/9124354.html
今日推荐