zoukankan      html  css  js  c++  java
  • [BOI2007]摩基亚

    题目:洛谷P4390、BZOJ1176。

    题目大意:

    给你一个(W imes W)的矩阵,初始每个数都为(S)。现在有若干操作:

    1. 给某个格子加上一个值;
    2. 询问某个子矩阵的值的和;
    3. 结束询问

    解题思路:

    CDQ分治。

    离线操作,把询问拆成4个矩阵(二维前缀和)。

    对(x)轴排序,分治询问,用左区间的修改来更新右区间的询问。由于(x)已被排序,我们直接用树状数组维护(y)的前缀和即可。

    也可以边CDQ边归并排序。

    时间复杂度(O(nlog^2 n))。

    C++ Code:

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #define LoveLive long long
    #define M 2000005
    int S,W,cnt=0;
    LoveLive bit[M];
    inline int readint(){
        int c=getchar(),d=0,f=0;
        for(;!isdigit(c);c=getchar())f=c=='-';
        for(;isdigit(c);c=getchar())
        d=(d<<3)+(d<<1)+(c^'0');
        return f?-d:d;
    }
    struct Qs{
        int type,x,y,id;LoveLive num;//type 0: modify; type 1: query.
        inline bool operator<(const Qs&rhs)const{return id<rhs.id;}
    }q[200020],t[200020];
    inline void add(int x,LoveLive y){for(int i=x;i<M;i+=i&-i)bit[i]+=y;}
    inline LoveLive ask(int x){LoveLive ans=0;for(int i=x;i;i-=i&-i)ans+=bit[i];return ans;}
    inline void clear(int x){for(int i=x;i<M;i+=i&-i)bit[i]=0;}
    void cdq(int l,int r){
        if(l<r){
            int mid=l+r>>1;
            cdq(l,mid),cdq(mid+1,r);
            int a=l,b=mid+1,c=l;
            while(a<=mid&&b<=r){
                if(q[a].x<=q[b].x){
                    if(!q[a].type)add(q[a].y,q[a].num);
                    t[c++]=q[a++];
                }else{
                    if(q[b].type)q[b].num+=ask(q[b].y);
                    t[c++]=q[b++];
                }
            }
            while(a<=mid){
                if(!q[a].type)add(q[a].y,q[a].num);
                t[c++]=q[a++];
            }
            while(b<=r){
                if(q[b].type)q[b].num+=ask(q[b].y);
                t[c++]=q[b++];
            }
            for(int i=l;i<=mid;++i)if(!q[i].type)clear(q[i].y);
            for(int i=l;i<=r;++i)q[i]=t[i];
        }
    }
    int main(){
        S=readint(),W=readint();
        for(int opt=readint();opt^3;opt=readint()){
            if(opt==1){
                int x=readint(),y=readint(),p=readint();
                ++cnt;
                q[cnt]=(Qs){0,x,y,cnt,p};
            }else{
                int x1=readint(),y1=readint(),x2=readint(),y2=readint();
                ++cnt;q[cnt]=(Qs){1,x1-1,y1-1,cnt,0};
                ++cnt;q[cnt]=(Qs){1,x1-1,y2,cnt,0};
                ++cnt;q[cnt]=(Qs){1,x2,y1-1,cnt,0};
                ++cnt;q[cnt]=(Qs){1,x2,y2,cnt,0};
            }
        }
        cdq(1,cnt);
        std::sort(q+1,q+cnt+1);
        for(int i=1;i<=cnt;++i)
        if(q[i].type){
            printf("%d
    ",int(q[i+3].num-q[i+2].num-q[i+1].num+q[i].num+1ll*S*(q[i+3].y-q[i].y)*(q[i+3].x-q[i].x)));i+=3;
        }
        return 0;
    }
  • 相关阅读:
    围棋GO
    Android 四大组件------Activity
    android studio----设备兼容
    android UI开发--------Action Bar
    开发调试工具----DDMS
    RxJava的使用
    Atlas框架
    Android studio上git的使用
    AS上git的使用与遇到的问题
    picasso-安卓的图片下载缓存库
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/9287182.html
Copyright © 2011-2022 走看看