zoukankan      html  css  js  c++  java
  • 【BZOJ】1176: [Balkan2007]Mokia(cdq分治)

    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
    ", 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

  • 相关阅读:
    企业移动视频通话会议EasyRTC视频会议通话系统开拓视频会议行业新前景
    安防网络摄像头海康大华硬盘录像机视频流媒体服务器EasyNVR调用接口时提示未授权问题解决方案
    安防RTSP_Onvif网络摄像头互联网直播视频流媒体服务器在使用过程中如何保存用户登录时的信息
    RTSP、RTMP、HTTP-FLV、 HLS安防网络摄像头互联网直播音视频流媒体服务器EasyNVR如何实现密码的MD5加密
    安防RTSP_Onvif网络摄像头互联网直播视频流媒体服务器EasyNVR如何解决视频流Ajax跨域访问的问题
    Python之网路编程利用threading模块开线程
    Python之网路编程之线程介绍
    Python之网路编程之进程池及回调函数
    Python之网路编程之-互斥锁与进程间的通信(IPC)及生产者消费者模型
    Python之网路编程利用multiprocessing开进程
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4135724.html
Copyright © 2011-2022 走看看