1176: [Balkan2007]Mokia/2683: 简单题 CDQ分治+树状数组
2016-02-29 20:12
375 查看
论文题,简要说一下做法吧。
用solve(l,r)solve(l,r)表示对于每一个queryquery操作ii,将[l..i−1][l..i-1]中的addadd操作在ii的矩形范围内的都累加起来,要求的是solve(1,n)solve(1,n)。
那么对于solve(l,r)solve(l,r),依旧是分治处理solve(l,mid)solve(l,mid)和solve(mid+1,r)solve(mid+1,r),然后我们考虑区间[l,mid][l,mid]中的点对区间[mid+1,r][mid+1,r]中的矩形的影响,问题转化为求一些点在一些矩形范围内的权值和,我们将第一维排序,第二维用树状数组维护前缀和,然后把一个query拆为四个操作加加减减求解就行了。
最后再膜CDQ
用solve(l,r)solve(l,r)表示对于每一个queryquery操作ii,将[l..i−1][l..i-1]中的addadd操作在ii的矩形范围内的都累加起来,要求的是solve(1,n)solve(1,n)。
那么对于solve(l,r)solve(l,r),依旧是分治处理solve(l,mid)solve(l,mid)和solve(mid+1,r)solve(mid+1,r),然后我们考虑区间[l,mid][l,mid]中的点对区间[mid+1,r][mid+1,r]中的矩形的影响,问题转化为求一些点在一些矩形范围内的权值和,我们将第一维排序,第二维用树状数组维护前缀和,然后把一个query拆为四个操作加加减减求解就行了。
最后再膜CDQ
[code]#include<iostream> #include<cstdio> #include<algorithm> #define N 200005 #define lowbit(i) (i&(-i)) using namespace std; int s,w,cnt,total; struct node {int x,y,id,dfn,val,opt;} q ,nq ; int tree[N*10],ans ; inline int read() { int a=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();} return a*f; } inline bool operator<(node a,node b) { if (a.x==b.x&&a.y==b.y) return a.opt<b.opt; return a.x==b.x?a.y<b.y:a.x<b.x; } inline void add(int x,int val) { for (int i=x;i<=w;i+=lowbit(i)) tree[i]+=val; } inline int query(int x) { int tmp=0; for (int i=x;i;i-=lowbit(i)) tmp+=tree[i]; return tmp; } void solve(int l,int r) { if (l==r) return; int mid=l+r>>1,p1=l,p2=mid+1; for (int i=l;i<=r;i++) { if (q[i].id<=mid&&!q[i].opt) add(q[i].y,q[i].val); if (q[i].id>mid&&q[i].opt) ans[q[i].dfn]+=q[i].val*query(q[i].y); } for (int i=l;i<=r;i++) if (q[i].id<=mid&&!q[i].opt) add(q[i].y,-q[i].val); p1=l; p2=mid+1; for (int i=l;i<=r;i++) if (q[i].id<=mid) nq[p1++]=q[i]; else nq[p2++]=q[i]; for (int i=l;i<=r;i++) q[i]=nq[i]; solve(l,mid); solve(mid+1,r); } int main() { s=read(); w=read(); for (;;) { int opt=read(); if (opt==3) break; if (opt==1) q[++cnt].x=read(),q[cnt].y=read(),q[cnt].val=read(),q[cnt].id=cnt; else { total++; int x1=read(),y1=read(),x2=read(),y2=read(); q[++cnt].x=x1-1; q[cnt].y=y1-1; q[cnt].id=cnt; q[cnt].dfn=total; q[cnt].val=1; q[cnt].opt=1; q[++cnt].x=x1-1; q[cnt].y=y2; q[cnt].id=cnt; q[cnt].dfn=total; q[cnt].val=-1; q[cnt].opt=1; q[++cnt].x=x2; q[cnt].y=y1-1; q[cnt].id=cnt; q[cnt].dfn=total; q[cnt].val=-1; q[cnt].opt=1; q[++cnt].x=x2; q[cnt].y=y2; q[cnt].id=cnt; q[cnt].dfn=total; q[cnt].val=1; q[cnt].opt=1; } } sort(q+1,q+cnt+1); solve(1,cnt); for (int i=1;i<=total;i++) printf("%d\n",ans[i]); return 0; }
相关文章推荐
- css练习——图书网站(head)
- 【LeetCode】89. Gray Code
- 【POJ1741】Tree【点分治】
- 设计模式--工厂设计模式
- Android手机两种方式获取IP地址
- 初次接触kmp看毛片算法
- Low-rank representation with local constraint for graph construction
- 广义表
- Android上3G/4G模组调试
- 《Java实战开发经典》第五章5.8
- 谨以此文献给软件行业的同仁们(群转发)
- Django学习-01
- 安卓开发——报错:duplicate files copied in apk meta-inf/License.txt
- IOS 证书失效
- android 中的一些焦点处理(listView GridView 抢焦点 与focus技巧)
- 102. Binary Tree Level Order Traversal
- 南阳ACM 题目275:队花的烦恼一 Java版
- 南阳ACM 题目275:队花的烦恼一 Java版
- Linux 交换分区
- 绑定。