zoukankan      html  css  js  c++  java
  • CCNU 校赛J---分桶法

    题意如上,标程是线段树,每个节点维护  a方的和,b方的和,ab的和,修改就是矩阵乘法,当然区间修改还要lazy标记。。

    这里考虑一个思维含量较低的分块做法。。

    平方分割法的复杂度为O(n*n^1/2),是要比线段树复杂度高的,但是由于分块做法一般常数小,所以如果不是时间限制卡的很紧,很多题是可以水过去的。

    对于这道题目,最大的问题就是区间修改,我们可以仿照线段树里面的lazy思想对于每一个块加一个lazy标记,当我们要修改一个块的时候,如果它是lazy的就把他整个更新一遍就行了,这样子复杂度不变也保证了正确性。

    没块维护∑a^2,∑b^2,∑ab,还有一个lazy标记和2*2的变化矩阵(实现lazy思想)

    接下来就是普通的分块做法了,每次修改  左-中-右  分别修改,查询同理,注意lazy的使用。

    PS。这题我写的很残疾。。要跑1.5秒。。标程1s,据说现场过题的队伍的分块比标程跑的都快,继续加油吧,蒟蒻!

    PPS。我知道为什么残疾了,多亏雕爷指导,其实这个取模有深意,直接unsigned int就不用取模了(计组没学好),省去很多时间。。这样跑得就比标程快了。。

    <pre name="code" class="cpp">#include <iostream>
    #include <stdio.h>
    #include <cstring>
    #include <cmath>
    using namespace std;
    int n,m;
    unsigned int  a[100005];
    unsigned int  b[100005];
    
    int big;
    unsigned int ss,x,y,p,q,r,s;
    
    unsigned int  a2[600];
    unsigned int  b2[600];
    unsigned int  ab[600];
    bool flag[600];
    unsigned int  ch[600][2][2];
    
    void init(){
    
        for(int i=0;i<n;i++){
            a2[i/big]=a2[i/big]+a[i]*a[i] ;
            b2[i/big]=b2[i/big]+b[i]*b[i] ;
            ab[i/big]=ab[i/big]+a[i]*b[i] ;
        }
        for(int i=0;i<600;i++){
            ch[i][0][0]=1;ch[i][0][1]=0;
            ch[i][1][0]=0;ch[i][1][1]=1;
        }
    }
    unsigned int t1,t2,t3,tmp1,tmp2,ret;
    int L,R;
    unsigned int va1,va2,va3,va4;
    int fn;
    
    void update(){
        L=x/big,R=y/big;
        if(R==L){
            if(flag[L]){
                va1=ch[L][0][0],va2=ch[L][0][1],va3=ch[L][1][0],va4=ch[L][1][1];
                fn=(L+1)*big;
                for(int i=L*big;i<fn;i++){
                    tmp1=va1*a[i]+va2*b[i] ;
                    tmp2=va3*a[i]+va4*b[i] ;
                    a[i]=tmp1;
                    b[i]=tmp2;
                }
                flag[L]=0;
                ch[L][0][0]=1; ch[L][0][1]=0;ch[L][1][0]=0; ch[L][1][1]=1;
            }
            for(int i=x;i<=y;i++){
                a2[R]=a2[R]-a[i]*a[i] ;
                b2[R]=b2[R]-b[i]*b[i] ;
                ab[R]=ab[R]-a[i]*b[i] ;
                tmp1=p*a[i] +q*b[i] ;
                tmp2=r*a[i] +s*b[i] ;
                a[i]=tmp1;
                b[i]=tmp2;
                a2[R]=a2[R]+a[i]*a[i] ;
                b2[R]=b2[R]+b[i]*b[i] ;
                ab[R]=ab[R]+a[i]*b[i] ;
            }
            return;
        }
        if(flag[L]){
            fn=(L+1)*big;
            va1=ch[L][0][0],va2=ch[L][0][1],va3=ch[L][1][0],va4=ch[L][1][1];
            for(int i=L*big;i<fn;++i){
                tmp1=va1*a[i] +va2*b[i] ;
                tmp2=va3*a[i] +va4*b[i] ;
                a[i]=tmp1;
                b[i]=tmp2;
            }
            flag[L]=0;
            ch[L][0][0]=1; ch[L][0][1]=0; ch[L][1][0]=0; ch[L][1][1]=1;
        }
        fn = (L+1)*big;
        for(int i=x;i<fn;++i){
            a2[L]=a2[L]-a[i]*a[i] ;
            b2[L]=b2[L]-b[i]*b[i] ;
            ab[L]=ab[L]-a[i]*b[i] ;
            tmp1=p*a[i] +q*b[i] ;
            tmp2=r*a[i] +s*b[i] ;
            a[i]=tmp1;b[i]=tmp2;
            a2[L]=a2[L]+a[i]*a[i] ;
            b2[L]=b2[L]+b[i]*b[i] ;
            ab[L]=ab[L]+a[i]*b[i] ;
        }
        if(flag[R]){
            fn=(R+1)*big;
            va1=ch[R][0][0],va2=ch[R][0][1],va3=ch[R][1][0],va4=ch[R][1][1];
            for(int i=R*big;i<fn;i++){
                tmp1=va1*a[i] +va2*b[i] ;
                tmp2=va3*a[i] +va4*b[i] ;
                a[i]=tmp1; b[i]=tmp2;
            }
            ch[R][0][0]=1; ch[R][0][1]=0; ch[R][1][0]=0; ch[R][1][1]=1;
            flag[R]=0;
        }
        for(int i=R*big;i<=y;++i){
                tmp1=p*a[i] +q*b[i] ;
                tmp2=r*a[i] +s*b[i] ;
                a2[R]=a2[R]-a[i]*a[i] ;
                b2[R]=b2[R]-b[i]*b[i] ;
                ab[R]=ab[R]-a[i]*b[i] ;
                a[i]=tmp1;b[i]=tmp2;
                a2[R]=a2[R]+a[i]*a[i] ;
                b2[R]=b2[R]+b[i]*b[i] ;
                ab[R]=ab[R]+a[i]*b[i] ;
        }
    
        for(int i=L+1;i<R;++i){
            va1=p*ch[i][0][0]+q*ch[i][1][0] ;va2=p*ch[i][0][1]+q*ch[i][1][1] ;
            va3=r*ch[i][0][0]+s*ch[i][1][0] ;va4=r*ch[i][0][1]+s*ch[i][1][1] ;
            ch[i][0][0]=va1;ch[i][0][1]=va2;ch[i][1][0]=va3;ch[i][1][1]=va4;
            flag[i]=1;
            t1=p*r*a2[i]+q*s*b2[i]+(p*s+r*q)*ab[i] ;
            t2=p*p*a2[i]+q*q*b2[i]+2*p*q*ab[i];
            t3=r*r*a2[i]+s*s*b2[i]+2*s*r*ab[i] ;
            ab[i]=t1;a2[i]=t2;b2[i]=t3;
        }
    
        return;
    }
    
    void query(){
        L=x/big,R=y/big;
        if(R==L){
            ret=0;
            va1=ch[L][0][0],va2=ch[L][0][1],va3=ch[L][1][0],va4=ch[L][1][1];
            if(flag[L]){
            fn=(L+1)*big;
            for(int i=L*big;i<fn;i++){
                tmp1=va1*a[i]+va2*b[i];
                tmp2=va3*a[i]+va4*b[i];
                a[i]=tmp1; b[i]=tmp2;
            }
            flag[L]=0;
            ch[L][0][0]=1; ch[L][0][1]=0; ch[L][1][0]=0; ch[L][1][1]=1;
            }
            for(int i=x;i<=y;i++){
                ret=ret+a[i]*b[i] ;
            }
            printf("%u
    ",ret );
            return;
        }
        ret=0;
        if(flag[L]){
            va1=ch[L][0][0],va2=ch[L][0][1],va3=ch[L][1][0],va4=ch[L][1][1];
            fn = (L+1)*big;
            for(int i=L*big;i<fn;i++){
                tmp1=va1*a[i] +va2*b[i];
                tmp2=va3*a[i] +va4*b[i];
                a[i]=tmp1;b[i]=tmp2;
            }
            flag[L]=0;
            ch[L][0][0]=1; ch[L][0][1]=0; ch[L][1][0]=0; ch[L][1][1]=1;
        }
        fn = (L+1)*big;
        for(int i=x;i<fn;i++){
            ret=ret+a[i]*b[i];
        }
        if(flag[R]){
            va1=ch[R][0][0],va2=ch[R][0][1],va3=ch[R][1][0],va4=ch[R][1][1];
            fn = (R+1)*big;
            for(int i=R*big;i<fn;i++){
                tmp1=va1*a[i]+va2*b[i];
                tmp2=va3*a[i]+va4*b[i];
                a[i]=tmp1;
                b[i]=tmp2;
            }
            flag[R]=0;
            ch[R][0][0]=1; ch[R][0][1]=0; ch[R][1][0]=0; ch[R][1][1]=1;
        }
        for(int i=R*big;i<=y;i++){
            ret=ret+a[i]*b[i];
        }
        for(int i=L+1;i<R;i++){
            ret=ret+ab[i] ;
        }
        printf("%u
    ",ret);
        return;
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        big=sqrt(n);
        for(int i=0;i<n;i++){
            scanf("%u",&a[i]);
        }
        for(int i=0;i<n;i++){
           scanf("%u",&b[i]);
        }
        init();
        for(int i=0;i<m;i++){
            scanf("%u",&ss);
            if(ss==1){
                scanf("%u%u%u%u%u%u",&x,&y,&p,&q,&r,&s);
                --x;--y;
                update();
            }
            else{
                scanf("%u%u",&x,&y);
                --x;--y;
                query();
            }
        }
        return 0;
    }
    



    
    
    
  • 相关阅读:
    hdu 1372 Knight Moves
    hdu 1253 胜利大逃亡
    nyoj 737 石子合并 经典区间 dp
    nyoj 737 石子合并 http://blog.csdn.net/wangdan11111/article/details/45032519
    nyoj 55 懒省事的小明
    C++ STL priority_queue
    Code forces363D Renting Bikes
    性能测试分享:jmeter性能监控(一)
    性能测试培训:WebSocket协议的接口性能之Jmeter
    翻译一篇文章:It's Difficult to Grow a Test Developer(成为测试开发工程师的艰辛)
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672569.html
Copyright © 2011-2022 走看看