【BOI2007】【BZOJ1176】Mokia

1176: [Balkan2007]Mokia

Time Limit: 30 Sec Memory Limit: 162 MB

Submit: 1059 Solved: 432

[Submit][Status][Discuss]

Description

维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.

Input

第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小

接下来每行为一下三种输入之一(不包含引号):

“1 x y a”

“2 x1 y1 x2 y2”

“3”

输入1:你需要把(x,y)(第x行第y列)的格子权值增加a

输入2:你需要求出以左上角为(x1,y1),右下角为(x2,y2)的矩阵内所有格子的权值和,并输出

输入3:表示输入结束

Output

对于每个输入2,输出一行,即输入2的答案

Sample Input

0 4

1 2 3 3

2 1 1 3 3

1 2 2 2

2 2 2 3 4

3

Sample Output

3

5

HINT

保证答案不会超过int范围

Source

cdq分治的模板题然而我现在才做这个题。。。

差分一下询问操作。对所有操作按y排序。

树状数组维护一下。然后就可以了。

自从看过了Tsinsen上的姿势分

我写代码都开始丧心病狂了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 200000
#define SIZE 2000010
#define lowbit(x) (x&(-x))
using namespace std;
int w;
int top,opt,L,R,l,r,delta,Top;
struct Query
{
    int op;
    int x,y,A;
    int t,id;
    bool operator <(const Query& a)const
    {
        if (x == a.x && y == a.y) return op < a.op;
        if (x == a.x) return y < a.y;
        return x < a.x;
    }
}que[MAXN],newq[MAXN];
int ans[MAXN],c[SIZE];
inline void in(int &x)
{
    x=0;char ch = getchar();
    while (!(ch >= ‘0‘ && ch <= ‘9‘))   ch = getchar();
    while (ch >= ‘0‘ && ch <= ‘9‘)  x = x * 10 + ch - ‘0‘,ch = getchar();
}
inline void add(int i,int x)
{
    while (i && i <= w) c[i] += x,i += lowbit(i);
}
inline int query(int i)
{
    int ret = 0;
    while (i) ret += c[i],i -= lowbit(i);
    return ret;
}
inline void Solve(int l,int r)
{
    int mid = (l + r) >> 1,tp1 = l,tp2 = mid + 1;
    if (l == r) return;
    for (int i = l;i <= r;i++)
    {
        if (que[i].t <= mid && que[i].op == 1)  add(que[i].y,que[i].A);
        if (que[i].t > mid && que[i].op == 2)   ans[que[i].id] += query(que[i].y) * que[i].A;
    }
    for (int i = l;i <= r;i++)
        if (que[i].t <= mid && que[i].op == 1) add(que[i].y,-que[i].A);
    for (int i = l;i <= r;i++)
        if (que[i].t <= mid) newq[tp1++] = que[i];
        else newq[tp2++] = que[i];
    memcpy(que+l,newq+l,sizeof(Query)*(r - l + 1));
    Solve(l,mid);Solve(mid+1,r);
}
int main()
{
    freopen("mokia.in","r",stdin);
    freopen("mokia.out","w",stdout);
    in(opt);in(w);
    while (1)
    {
        in(opt);
        if (opt == 3) break;
        switch (opt)
        {
            case 1:
                in(L);in(R);in(delta);
                que[++top].op = opt;que[top].x = L;que[top].y = R;que[top].A = delta;que[top].t = top;
                break;
            case 2:
                in(L);in(R);in(l);in(r);
                que[++top].op = opt;que[top].x = L - 1;que[top].y = R - 1;que[top].t = top;que[top].A = 1;que[top].id = ++Top;
                que[++top].op = opt;que[top].x = L - 1;que[top].y = r;que[top].t = top;que[top].A = -1;que[top].id = Top;
                que[++top].op = opt;que[top].x = l;que[top].y = R - 1;que[top].t = top;que[top].A = -1;que[top].id = Top;
                que[++top].op = opt;que[top].x = l;que[top].y = r;que[top].t = top;que[top].A = 1;que[top].id = Top;
                break;
        }
    }
    sort(que + 1,que + top + 1);
    Solve(1,top);
    for (int i = 1;i <= Top;i++)    printf("%d\n",ans[i]);
}
时间: 2025-01-05 20:42:57

【BOI2007】【BZOJ1176】Mokia的相关文章

题解 P4393 【[BOI2007]Sequence 序列问题】

Solution: 对于每个很大的数,基于贪心,我们显然要让它合并次数尽可能少,以保证最终总代价最小. 如图: 考虑中间那个最大的 $maxn$,很显然,将其与其它的合并代价显然更大,所以,我们不可能先用 $maxn$ 去和其它的合并. 但是,由于最终目标长度为1,所以无论如何,$maxn$ 终将被合并,可以先考虑将比它小的全部合并,最后再与它合并,以减少它参与合并的次数. 不难想到,可以先将 $maxn$ 左边全部合并,再将其右边全部合并,最后,再让左右两部分与它合并,这样可以保证比先合并 $

【BOI2007】摩基亚Mokia

P1948 - [BOI2007]摩基亚Mokia Description 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如"用户C的位置在哪?"的问题,精确到毫米.但其真正高科技之处在于,它能够回答形如"给定区域内有多少名用户?"的问题. 在定位系统中,世界被认为是一个W * W的正方形区域,由1 * 1的方格组成.每个方格都有一个坐标(x,y),1<=x,y<=W.坐标的编号从1开始

【BZOJ1176】Mokia(CDQ分治)

[BZOJ1176]Mokia(CDQ分治) 题面 BZOJ权限题啊,,,, dbzoj真好 Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. Input 第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小 接下来每行为一下三种输入之一(不包含引号): "1 x y a" "2 x1 y1 x2 y2"

【Windows10&nbsp;IoT开发系列】配置篇

原文:[Windows10 IoT开发系列]配置篇 Windows10 For IoT是Windows 10家族的一个新星,其针对不同平台拥有不同的版本.而其最重要的一个版本是运行在Raspberry Pi.MinnowBoard和Galileo平台上的核心版.本文重点针对Raspberry Pi平台的Windwos10 IoT配置做介绍. Windows 10 IoT Editions ​一:设置你的电脑. 注:​开发Windows10 IoT的电脑需要Visual Studio 2015.

【Windows10&nbsp;IoT开发系列】PowerShell的相关配置

原文:[Windows10 IoT开发系列]PowerShell的相关配置 可使用 Windows PowerShell 远程配置和管理任何 Windows 10 IoT 核心版设备.PowerShell 是基于任务的命令行 Shell 和脚本语言,专为进行系统管理而设计. 1.​启动 PowerShell (PS) 会话 注:若要使用装有Windows10 IoT Core设备启动PS会话,首先需要在主机电脑与设备之间创建信任关系. ​启动 Windows IoT 核心版设备后,与该设备相连的

【Windows10&nbsp;IoT开发系列】API&nbsp;移植工具

原文:[Windows10 IoT开发系列]API 移植工具 Windows 10 IoT Core 中是否提供你的当前 Win32 应用程序或库所依赖的 API? 如果不提供,是否存在可使用的等效 API? 此工具可以为你回答这些问题,并协助你将你的当前 Win32 应用程序和库迁移到 Windows IoT Core. Windows 10 IoT 核心版 API 移植工具可在 ms-iot/iot-utilities github 存储库中找到.下载存储库 zip 并将 IoTAPIPor

【Windows10&nbsp;IoT开发系列】“Hello,World!”指导

原文:[Windows10 IoT开发系列]"Hello,World!"指导 本文主要是介绍使用C#来开发一个可以运行在Raspberry Pi2上的一个基本项目. ​1.在启动Visual Studio 2015后,选择"文件"→"新建项目". ​在打开的"新建项目"对话框中,选择"通用". ​选择第一个项目"空白应用(通用Windows)" 新建项目 ​注:如果这是你创建的第一个项

【opencv入门之二】感兴趣区域ROI,线性混合addWeighted

参考网站: http://blog.csdn.net/poem_qianmo/article/details/20911629 1.感兴趣区域ROI //[2]定义一个Mat类型并给其设定ROI区域 Mat imageROI = srcImage1( Rect(200, 250, logoImage.cols, logoImage.rows )); //[3]加载掩摸(必须是灰度图) Mat mask = imread( "dota_logo.jpg", 0 ); //[4]将掩摸拷贝

【Windows10&nbsp;IoT开发系列】Powershell命令行实用程序

原文:[Windows10 IoT开发系列]Powershell命令行实用程序 更新帐户密码: 强烈建议你更新默认的管理员帐户密码.若要更新帐户密码,你可以发出以下命令: net user Administrator [new password]​ (其中 [new password] 表示你选择的强密码). 创建本地用户帐户: 如果你想要授予其他人访问你的 Windows IoT Core 设备的权限,你可以通过在 net user [username] [password] /add​ 中键

【python之路35】网络编程之socket相关

Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Unix,而Unix/Linux基本哲学之一就是"一切皆文件",对于文件用[打开][读写][关闭]模式来操作.socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO.打开.关闭) socket和file的区别: fil