bzoj 1176

收获:

  1、min, max, sum, 属于判定,等询问是”对象对答案贡献独立“,即不需要其他对象就了能更新答案,并保证只要所有对象更新过答案,那么该答案就是正确的。大概这就是所谓的”修改独立“。

  2、处理”先把所有修改给你,再询问“问题时,这道题要用到降维思想,就是处理的顺序也是一维,并且这维可以差分。那么就将二维问题变成了一维问题。(最值不满足差分性)。

 1 /**************************************************************
 2     Problem: 1176
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:6896 ms
 7     Memory:42684 kb
 8 ****************************************************************/
 9
10 #include <cstdio>
11 #include <algorithm>
12 #define N 2000010
13 #define M 340010
14 using namespace std;
15
16 typedef long long dnt;
17
18 struct Proc {
19     int opt, tim;
20     int id;
21     int x, y, v;
22     int t, b;
23     Proc(){}
24     Proc( int opt, int tim, int x, int y, int v ):opt(opt),tim(tim),id(0),x(x),y(y),v(v),t(0),b(0) {}
25     Proc( int opt, int tim, int id, int y, int t, int b ):opt(opt),tim(tim),id(id),x(0),y(y),v(0),t(t),b(b) {}
26     bool operator<( const Proc &o ) const {
27         return y<o.y || (y==o.y && opt<o.opt);
28     }
29 };
30
31 int n, m, s;
32 Proc proc[M]; int idp;
33 dnt bit[N];
34 dnt ans[N]; int ida;
35
36 void modify( int x, int v ) {
37     for( int i=x; i<=n; i+=i&-i )
38         bit[i] += v;
39 }
40 dnt query( int x ) {
41     dnt rt=0LL;
42     for( int i=x; i; i-=i&-i )
43         rt += bit[i];
44     return rt;
45 }
46 dnt query( int t, int b ) {
47     return query(b)-query(t-1);
48 }
49 void cdq( int lf, int rg ) {
50     if( lf==rg ) return;
51     int mid=(lf+rg)>>1;
52     cdq(lf,mid);
53     cdq(mid+1,rg);
54     sort( proc+lf, proc+rg+1 );
55     for( int i=lf; i<=rg; i++ ) {
56         Proc &p = proc[i];
57         if( p.opt==1 && p.tim<=mid ) {
58             modify( p.x, p.v );
59         } else if( p.opt==2 && p.tim>mid ) {
60             ans[p.id] -= query( p.t, p.b );
61         } else if( p.opt==3 && p.tim>mid ) {
62             ans[p.id] += query( p.t, p.b );
63         }
64     }
65     for( int i=lf; i<=rg; i++ ) {
66         Proc &p = proc[i];
67         if( p.opt==1 && p.tim<=mid )
68             modify( p.x, -p.v );
69     }
70 }
71 int main() {
72     scanf( "%d%d", &s, &n );
73     for( int i=1; ; i++ ) {
74         int opt;
75         scanf( "%d", &opt );
76         if( opt==3 ) break;
77         if( opt==1 ) {
78             int x, y, v;
79             scanf( "%d%d%d", &x, &y, &v );
80             idp++;
81             proc[idp] = Proc( opt, idp, x, y, v );
82         } else {
83             int x0, y0, x1, y1;
84             scanf( "%d%d%d%d", &x0, &y0, &x1, &y1 );
85             ida++;
86             ans[ida] += (dnt) (y1-y0+1)*(x1-x0+1)*s;
87             idp++;
88             proc[idp] = Proc( 2, idp, ida, y0-1, x0, x1 );
89             idp++;
90             proc[idp] = Proc( 3, idp, ida, y1, x0, x1 );
91         }
92     }
93     cdq( 1, idp );
94     for( int i=1; i<=ida; i++ )
95         printf( "%lld\n", ans[i] );
96 }

时间: 2024-10-18 20:02:10

bzoj 1176的相关文章

bzoj 1176 [Balkan2007]Mokia - CDQ分治 - 树状数组

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 输入

【BZOJ 1176】【Balkan 2007】Mokia

http://www.lydsy.com/JudgeOnline/problem.php?id=1176 整体二分的例题 把每个询问拆成四个询问,整体二分里x坐标递增,按x坐标扫的时候用树状数组维护y坐标前缀和. 一开始想复杂了,按cdq分治先solve左边再处理中间再solve右边,这样每次都要对x坐标排序,常数巨大,T了好几次TwT 后来参考了别人的代码,发现自己一开始就想复杂了.这道题不需要在solve完后还是保持原来的按x坐标递增的顺序,也不需要先处理出左边的信息才能更新右边的信息. 这

BZOJ 1176 Balkan 2007 Mokia CDQ分治

题目大意:有一些操作,给一个坐标代表的点加上一个数,和求出一个矩形中的所有数的和. 思路:一眼题,二位树状数组水过. ... .. . 哪里不对?W<=2000000.逗我?这n^2能开下? 这个时候CDQ神牛又来帮助我们了. 这个题应该算是CDQ分治的模板题了吧,简单分析一下,其实不难. 写这个题之前建议写一下BZOJ 1935 SHOI 2007 Tree 园丁的烦恼 树状数组这个题,是本题的简化版. 按照正常的解法,我们应该建立一个二位的数据结构,然后分别维护两维的信息.如果用动态开点的线

BZOJ 1176: [Balkan2007]Mokia

一道CDQ分治的模板题,然而我De了一上午Bug...... 按时间分成左右两半,按x坐标排序然后把y坐标丢到树状数组里,扫一遍遇到左边的就add,遇到右边的query 几个弱智出了bug的点, 一是先分了左右两半再排序,保证的是这次的左右是上次没有计算过的贡献, for(int i=l;i<=r;i++) qs[i].k=(i>mid); sort(qs+l,qs+r+1,cmp2); 然后时间的先后是因为一开始就是按时间排好序的已经保证了. 二是矩阵的一个经典的套路就是拆成四部分差分查询.

[BZOJ 1176&amp;COGS 1752][BOI2007]Mokia(CDQ分治)

Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. Solution 这道在BZOJ上是权限题啊…然而我在cogs上找到了它 依旧是CDQ分治的论文题,CDQ太强辣… 把查询拆成四个前缀和的形式,在CDQ分治中用时间把操作分为两部分,保证两部分的x各自单调(只有x较小的操作才能对较大的操作产生影响),然后用树状数组维护y这一维 #include<

【BZOJ 1176】 [Balkan2007]Mokia

1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MB Submit: 736  Solved: 306 [Submit][Status] Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. Input 第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小 接下来每行为一下

BZOJ 1176 Mokia(cdq分治,解决一类在线查询问题)

题意:维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. 这题在bz是贵族题= =,没有链接了 解法:cdq分治,第一维是时间t,第二维是x,第三维是y:每个操作看作一个三维序(t, x, y):假设修改操作是(t, x, y),两个查询操作分别是(t1, x1, y1) 和 (t1, x2, y2):实际上就要问,有多少个修改操作,满足t<=t1,x1<=x&

BZOJ 1176 [Balkan2007]Mokia CDQ分治

题目大意: 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000. POJ1195的加强版 没记错的话上午这题还没有中文题目描述的说0.0 好迅速 首先这题看到W就知道二维树状数组挂了 看到M就发现离散化了也搞不了 0.0 这题似乎是CDQ分治被发现之后第二个解决的题目...不过只有会员才知道的世界,今天反应过来刷刷... 修改和询问放在一起分治,一个询问拆分成4个,树状数组处

【BZOJ 1176 2683】Mokia

Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.(在2683中,没有S,初始值为0). Input 第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小 接下来每行为一下三种输入之一(不包含引号): "1 x y a" "2 x1 y1 x2 y2" "3" 输入1:你需要把(x,y)