BZOJ 1176 Mokia
来源:互联网 发布:怎么样开淘宝充值店 编辑:程序博客网 时间:2024/06/06 03:30
1176: [Balkan2007]Mokia
Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 2389 Solved: 1072
[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:表示输入结束
裸CDQ,计算矩阵和可以利用以(1,1)为基点的矩阵相加减获得的ans值,实现方法为将询问操作分解为4个子操作。
N.B. 此题中w无用。。
以下为CDQ分治的操作步骤:
(1)把操作离线下来(离线的时候要记录每个操作的时间,即操作的编号),然后按x轴排序(必要时离散化);
(2)分治区间[L, R](L, R为时间,即操作的编号),取mid,从L到R遍历操作,将mid之前的修改加入一维树状数组,将mid之后的查询在一维树状数组里查询;(3)还原修改操作,从L到R遍历操作,遇到修改操作,将修改操作改回去。(如果是+c,那么-c);
(4)开一个临时数组,两个指针(一个指针指向左区间的左端点,另一个指针指向右区间的左端点),从L到R遍历操作,将mid之前的操作放到左区间,将mid之后的操作放到右区间。最后把临时数组赋值给操作数组;
(5)递归[L, mid],[mid + 1, R],回到(2)。递归的终点是L==R。注意,在分治的每一层的区间内,x轴都是有序的。虽然时间无序,但是我们遍历操作时按照mid来划分了;
N.B. 在分治的每一层的区间内,x轴都是有序的。虽然时间无序,但是我们遍历操作时按照mid来划分了。
#include<cstdlib>#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int maxn=2000005;struct opr{int d,t,val,qid,x,y;}l[maxn],point[maxn];int res[maxn],tr[maxn];int n,w,cnt,tim;int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}return x*f;}bool cmp(opr a,opr b){ if(a.x==b.x) { if(a.y==b.y)return a.d<b.d; return a.y<b.y; } return a.x<b.x;}int sum(int k) { int sum_=0; while(k) { sum_+=tr[k]; k-=k&-k; } return sum_; }void update(int k,int num) { while(k<=n) { tr[k]+=num; k+=k&-k; } } void cdq(int lt,int rt){if(lt==rt)return;int mid=(lt+rt)>>1;for(int i=lt;i<=rt;i++){if(l[i].d==1&&l[i].t<=mid)update(l[i].y,l[i].val);if(l[i].d==2&&l[i].t>mid)res[l[i].qid]+=l[i].val*sum(l[i].y);}for(int i=lt;i<=rt;i++)if(l[i].d==1&&l[i].t<=mid)update(l[i].y,-l[i].val);int p1=lt-1,p2=mid;for(int i=lt;i<=rt;i++){if(l[i].t<=mid)point[++p1]=l[i];else point[++p2]=l[i];}for(int i=lt;i<=rt;i++)l[i]=point[i];cdq(lt,mid);cdq(mid+1,rt);}int main(){w=read();n=read();int x,y,d1,d2,d,xx,yy;while(true){ d=read(); if(d==3)break;if(d==1){x=read();y=read();d1=read();l[++cnt]=(opr){1,cnt,d1,-1,x,y};}else{x=read();y=read();xx=read();yy=read();l[++cnt]=(opr){2,cnt,1,++tim,xx,yy};l[++cnt]=(opr){2,cnt,1,tim,x-1,y-1};l[++cnt]=(opr){2,cnt,-1,tim,xx,y-1};l[++cnt]=(opr){2,cnt,-1,tim,x-1,yy};}}sort(l+1,l+cnt+1,cmp);cdq(1,cnt);for(int i=1;i<=tim;i++)printf("%d\n",res[i]);return 0;}
- 【BZOJ 1176】 [Balkan2007]Mokia
- bzoj 1176: [Balkan2007]Mokia
- BZOJ 1176 [Balkan2007] Mokia
- bzoj 1176: [Balkan2007]Mokia
- BZOJ 1176 Mokia
- bzoj 1176 [Balkan2007]Mokia
- BZOJ 1176 Mokia
- bzoj 1176: [Balkan2007]Mokia
- 【分治】 BZOJ 1176 [Balkan2007]Mokia
- 【bzoj】【1176】【mokia】【cdq分治】
- BZOJ 1176: [Balkan2007]Mokia CDQ
- BZOJ 1176 [Balkan2007]Mokia CDQ分治
- BZOJ 1176 Balkan 2007 Mokia CDQ分治
- BZOJ 1176: [Balkan2007]Mokia CDQ分治
- bzoj 1176: [Balkan2007]Mokia 【CDQ分治】
- bzoj 1176: [Balkan2007]Mokia(cdq分治)
- 【BZOJ 1176】 [Balkan2007]Mokia cdq分治
- BZOJ 1176: [Balkan2007]Mokia (CDQ分治)
- (0001) JDBC直连MYSQL
- JAVA设计模式之抽象工厂模式
- 配置Tomcat-8.5.15 JVM内存参数
- c++ builder 中的 XMLDocument 类详解(6)
- java.lang.IllegalArgumentException: Invalid character found in method name
- BZOJ 1176 Mokia
- 编程基础(二)
- c++ builder 中的 XMLDocument 类详解(7)
- axis错误说明
- java集合
- 一、stormkafka之DynamicBrokersReader
- 创建线程的另一种方法-使用Android线程池
- 给php代码添加规范的注释phpDocumentor
- RYU实战,REST API流表控制(2)