Processing math: 100%

[BOI2007]摩基亚

题目:洛谷P4390、BZOJ1176。

题目大意:

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

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

解题思路:

CDQ分治。

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

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

也可以边CDQ边归并排序。

时间复杂度O(nlog2n)

C++ Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#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\n",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;
}

 

posted @   Mrsrz  阅读(200)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· .NET 进程 stackoverflow异常后,还可以接收 TCP 连接请求吗?
· SQL Server统计信息更新会被阻塞或引起会话阻塞吗?
阅读排行:
· 本地部署 DeepSeek:小白也能轻松搞定!
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
· 我们是如何解决abp身上的几个痛点
· 如何基于DeepSeek开展AI项目
历史上的今天:
2017-07-10 [HDU2874]Connections between cities
点击右上角即可分享
微信分享提示