http://www.lydsy.com/JudgeOnline/problem.php?id=1176

在写这题的时候思维非常逗啊。。。。。。。。2333。。。。。。。。。。。。。。。。。。。

最后不得不去看别人的代码。。

噗,,我怎么没想到二维前缀和。。。。。。。。。。。。。。。。。。。。

orz zyf

那么对于一个矩形,我们拆成四个点,那么就可以和add操作一起cdq分治!

orz

cdq分治的话很好想的:

定义$solve(l, r)$表示用l~mid来更新mid+1~r。

考虑如何$O(n)$更新:

首先我们可以先考虑x轴,如果是已经排序好了的话,直接扫过去更新y轴!这点利用了单调的思想。

而如何更新y轴呢?树状数组。

而拆点后如何维护二维前缀和呢?加加减减。

如何快速排序呢?在外边先排序过。

然后完了。

我之前写的cdq非常逗啊,,都没有拆点,直接单调队列暴力扫,但是为啥wa了?我对拍的时候看了一下答案,只有一些答案错了QAQ。。。

一些技巧请看代码,orz

(丧心病狂の加速,我们离散y轴再用bit维护233)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } const int N=170005, M=2000005; int tot, c[M];
inline void add(int x, const int &s) { for(; x<=tot; x+=x&-x) c[x]+=s; }
inline int sum(int x) { int ret=0; for(; x; x-=x&-x) ret+=c[x]; return ret; } int y[N*4], W, n, cnt, ans[N], S; struct dat { int x, y, id, pos, a; bool f; }p[N*5], t[N*5];
inline const bool cmp(const dat &a, const dat &b) { return a.x==b.x ? (a.y==b.y?a.pos<b.pos:a.y<b.y) : a.x<b.x; } void cdq(int l, int r) {
if(l==r) return;
int mid=(l+r)>>1, l1=l, l2=mid+1;
for1(i, l, r) {
if(p[i].id<=mid && !p[i].f) add(p[i].y, p[i].a);
if(p[i].id>mid && p[i].f) ans[p[i].pos]+=p[i].a*sum(p[i].y);
}
for1(i, l, r) if(p[i].id<=mid && !p[i].f) add(p[i].y, -p[i].a);
for1(i, l, r) if(p[i].id<=mid) t[l1++]=p[i]; else t[l2++]=p[i];
for1(i, l, r) p[i]=t[i];
cdq(l, mid); cdq(mid+1, r);
} int main() {
read(S); read(W);
int t=getint();
while(t!=3) {
if(t==1) { ++n; read(p[n].x); read(p[n].y); read(p[n].a); p[n].f=0; p[n].pos=0; p[n].id=n; y[++tot]=p[n].y; }
else {
int x1=getint(), y1=getint(), x2=getint(), y2=getint();
ans[++cnt]=S*(x2-x1+1)*(y2-y1+1);
p[++n].x=x1-1, p[n].y=y1-1, p[n].f=1, p[n].a=1; p[n].id=n; p[n].pos=cnt;
p[++n].x=x1-1, p[n].y=y2, p[n].f=1, p[n].a=-1; p[n].id=n; p[n].pos=cnt;
p[++n].x=x2, p[n].y=y1-1, p[n].f=1, p[n].a=-1; p[n].id=n; p[n].pos=cnt;
p[++n].x=x2, p[n].y=y2, p[n].f=1, p[n].a=1; p[n].id=n; p[n].pos=cnt;
y[++tot]=y1; y[++tot]=y2; y[++tot]=y1-1; y[++tot]=y2-1;
}
read(t);
}
sort(y+1, y+1+tot); tot=unique(y+1, y+1+tot)-y-1;
for1(i, 1, n) p[i].y=lower_bound(y+1, y+1+tot, p[i].y)-y;
sort(p+1, p+1+n, cmp);
cdq(1, n);
for1(i, 1, cnt) printf("%d\n", ans[i]); return 0;
}

  


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

【BZOJ】1176: [Balkan2007]Mokia(cdq分治)的更多相关文章

  1. BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 )

    考虑cdq分治, 对于[l, r)递归[l, m), [m, r); 然后计算[l, m)的操作对[m, r)中询问的影响就可以了. 具体就是差分答案+排序+离散化然后树状数组维护.操作数为M的话时间 ...

  2. BZOJ 1176[Balkan2007]Mokia(CDQ分治)

    1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 3381  Solved: 1520[Submit][S ...

  3. BZOJ 1176: [Balkan2007]Mokia [CDQ分治]

    题意: 有一个n * n的棋盘,每个格子内有一个数,初始的时候全部为0.现在要求维护两种操作: 1)Add:将格子(x, y)内的数加上A. 2)Query:询问矩阵(x0, y0, x1, y1)内 ...

  4. BZOJ 1176 [Balkan2007]Mokia ——CDQ分治

    [题目分析] 同BZOJ2683,只需要提前处理s对结果的影响即可. CDQ的思路还是很清晰的. 排序解决一维, 分治时间, 树状数组解决一维. 复杂度是两个log [代码] #include < ...

  5. BZOJ 1176: [Balkan2007]Mokia

    1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 2012  Solved: 896[Submit][St ...

  6. bzoj 1176: [Balkan2007]Mokia&&2683: 简单题 -- cdq分治

    2683: 简单题 Time Limit: 50 Sec  Memory Limit: 128 MB Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要 ...

  7. bzoj 1176 [Balkan2007]Mokia 【CDQ分治】

    W过大,很难在线维护,考虑离线算法 给每个操作加一个时间属性n,显然,对于n=i的询问,对它有影响的修改只在n<i中,所以可以CDQ(因为是按时间序读进来的,所以不用排序了 对于统计矩形和,可以 ...

  8. BZOJ1176: [Balkan2007]Mokia CDQ分治

    最近很不对啊=w= 写程序全是bug啊 ans数组开小了竟然一直不知道,小数据没问题大数据拍不过,交上去RE 蛋疼半天 这个主要把每次询问拆成3个询问. #include<cstdio> ...

  9. BZOJ 1176: [Balkan2007]Mokia KDtree

    Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin), ...

  10. BZOJ 1176 Mokia CDQ分治+树状数组

    1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1854  Solved: 821[Submit][St ...

随机推荐

  1. mybatis模糊查询语句

    articletitle like concat('%',#{articletitle},'%')

  2. ubuntu server激活即时通讯IM服务 Instant Messaging is not activated on this server

    转自:http://shine-it.net/index.php/topic,16469.msg28364.html ubuntu server 下 odoo激活及时通讯功能im OpenERP IM ...

  3. java线程同步: synchronized详解(转)

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this ...

  4. Tomcat中配置MySQL数据库连接池

    Web开发中与数据库的连接是必不可少的,而数据库连接池技术很好的优化了动态页与数据库的连接,相比单个连接数据库连接池节省了很大的资源.用一个通俗的比喻:如果一个人洗澡需花一桶水,那一百个人就要花一百桶 ...

  5. Apache Directory Studio

    Apache Directory Studio 是一个 LDAP 的工具平台,用来连接到任何 LDAP 服务器并进行管理和开发工作.主要功能:LDAP浏览器.LDIF编辑器.嵌入式 ApacheDS. ...

  6. 通过CSS3,实现元素覆盖效果

    在非常多站点中,我们都能够看到这种效果.当用户鼠标进入某一个元素后,下方就会有遮罩层上浮动画,如图: 今天我们就用hover伪类加上css3实现,没有使用不论什么JS <!DOCTYPE htm ...

  7. jquery api 常见api 元素操作例子

    append_prepend.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> ...

  8. brew install memcache get Error: Formulae found in multiple taps

    本篇文章由:http://xinpure.com/brew-install-memcache-get-error-formulae-found-in-multiple-taps/ 安装环境: Mac ...

  9. JAVA中的static方法

    static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static修饰的成员变量和成员方法独立于该类的任何 ...

  10. 用Visual studio2012在Windows8上开发内核驱动监视进程创建

    在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破.在Windows 95中,至少应用程序I/O操作是不受限制的,而在Win ...