ACdream 1157 Segments(cdq分治)
来源:互联网 发布:慈溪行知职高地址全称 编辑:程序博客网 时间:2024/06/05 05:08
学习了merge函数。
参考题解:http://blog.csdn.net/v5zsq/article/details/51083826
在ACdream上留下了一页半的wa和tle
总体来说,思路并不难。插入一条线段,就是在线段的起点+1,删除一条线段,就是-1,查询就是+0。在分治的时候,按照线段右端点降序排序。对于左区间的点,更新左端点所在位置。右区间的线段,查询左端点的前缀和统计。如果能像51nod那样查看数据就好了,调代码就方便多了。也不知道哪里写错了,模仿人家的代码写了一发。把离散化的方式换成我比较习惯的方式了。。。。
#include <bits/stdc++.h>using namespace std;#define lowbit(x) (x&(-x))const int MAXN = 220022;int n,tot;struct node{ int x,y,cnt,id,ans; bool operator<(const node& a) const { return y > a.y; }} p[MAXN],q[MAXN];bool cmpid(const node& a, const node& b){ return a.id < b.id;}int bit[MAXN];void add(int x, int v){ while(x <= tot) { bit[x] += v; x += lowbit(x); }}int sum(int x){ int ret = 0; while(x) { ret += bit[x]; x -= lowbit(x); } return ret;}void CDQ(int l, int r){ if(l >= r) return; int mid = (l+r) >> 1; CDQ(l,mid); CDQ(mid+1,r); sort(p+l,p+mid+1); sort(p+mid+1,p+r+1); int j = l; for(int i = mid+1; i <= r; ++i) { for(; j <= mid && p[j].y >= p[i].y; ++j) add(p[j].x,p[j].cnt); if(!p[i].cnt) p[i].ans += sum(p[i].x); } for(int i = l; i < j; ++i) add(p[i].x,-p[i].cnt); merge(p+l,p+mid+1,p+mid+1,p+r+1,q); for(int i = 0; i < r-l+1; ++i) p[l+i]=q[i];}int res,l[MAXN],r[MAXN];vector<int> vec;int getid(int x){ return lower_bound(vec.begin(),vec.end(),x)-vec.begin()+1;}int main(){ while(scanf("%d",&n) != EOF) { vec.clear(); memset(bit,0,sizeof(bit)); res = 1; for(int i = 1; i <= n; ++i) { p[i].id = i; p[i].ans = 0; char s; int temp; scanf(" %c",&s); if(s == 'D') { scanf("%d %d",&p[i].x,&p[i].y); p[i].cnt = 1; l[res] = p[i].x; r[res++] = p[i].y; vec.push_back(p[i].x); vec.push_back(p[i].y); } else if(s == 'Q') { scanf("%d %d",&p[i].x,&p[i].y); p[i].cnt = 0; vec.push_back(p[i].x); vec.push_back(p[i].y); } else { scanf("%d",&temp); p[i].x = l[temp]; p[i].y = r[temp]; p[i].cnt = -1; } } sort(vec.begin(),vec.end()); vec.erase(unique(vec.begin(),vec.end()),vec.end()); tot = vec.size(); for(int i = 1; i <= n; ++i) { p[i].x = getid(p[i].x); p[i].y = getid(p[i].y); } CDQ(1,n); sort(p+1,p+1+n,cmpid); for(int i = 1; i <= n; ++i) if(!p[i].cnt) printf("%d\n",p[i].ans); } return 0;}
阅读全文
0 0
- 【ACdream】1157 Segments cdq分治
- ACdream 1157 Segments 【CDQ分治】
- ACdream 1157 Segments(cdq分治)
- ACdream 1157 Segments(CDQ分治)
- ACdream群OJ 1157 cdq分治
- cdq分治
- cdq分治
- cdq分治
- cdq分治
- 时间分治(cdq分治)
- 学习笔记: cdq分治
- bsoj2653 cdq分治
- 【CDQ分治】数据
- BZOJ3262【CDQ分治】
- BZOJ1492【CDQ分治】
- CDQ分治优化DP
- HDU 4456 CDQ分治
- cdq分治模板
- opencv学习一: Fourier变换
- python中的单例
- bzoj 1296 [SCOI2009]粉刷匠 (dp)
- 六、tensorflow之添加层。
- 和大于S的最小子数组-LintCode
- ACdream 1157 Segments(cdq分治)
- 对称密码
- android adapter控件及高级控件
- 深度学习所需的python-学习笔记4
- 安卓获取手机短信(Contentprovider)
- 最短路径—Dijkstra算法(C#)
- 无线自动轮播,获取网络上的图片+scrollView+listView 联动
- 74HC573芯片介绍
- js实现常见排序算法