poj2528 Mayor's posters(线段树,离散化)
2015-07-10 16:37
232 查看
离散化的思想:
对于这样的数据
(3,10000),
(9,1000000),
(5,100000),
(1,1000),
(7,1000000)
我们可以将其处理为
(2,7),
(5,9),
(3,8),
(1,6),
(4,9)
我们再对离散化之后的数据进行处理就行了。
题目意思:
n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000)。
求出最后还能看见多少张海报。
参考代码:
n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000)。
求出最后还能看见多少张海报。
对于这样的数据
(3,10000),
(9,1000000),
(5,100000),
(1,1000),
(7,1000000)
我们可以将其处理为
(2,7),
(5,9),
(3,8),
(1,6),
(4,9)
我们再对离散化之后的数据进行处理就行了。
题目意思:
n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000)。
求出最后还能看见多少张海报。
参考代码:
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> using namespace std; const int MAXN = 10000+5; struct Node{ int l,r; int c; }tree[14*MAXN]; //线段树 struct Seg{ int l,r; }s[MAXN]; //存储报纸的范围 struct Seg2{ int p; int index; }a[2*MAXN]; //存放端点信息 bool cmp(Seg2 x,Seg2 y){ return x.p<y.p; } int color[2*MAXN]; int ans=0; void build(int node,int l,int r){ tree[node].l=l,tree[node].r=r,tree[node].c=0; if (l==r) return; build(node*2,l,(l+r)/2); build(node*2+1,(l+r)/2+1,r); } void update(int node,int l,int r,int v){ //cout<<l<<" "<<r<<endl; if (tree[node].l>=l && tree[node].r<=r){ tree[node].c=v; return; } if (tree[node].c>0){ tree[2*node].c=tree[2*node+1].c=tree[node].c; tree[node].c=0; } int mid=(tree[node].l+tree[node].r)/2; if (r<=mid) update(2*node,l,r,v); else if (mid<l) update(2*node+1,l,r,v); else{ update(2*node,l,mid,v); update(2*node+1,mid+1,r,v); } } void count(int node){ if (tree[node].c>0){ if (color[tree[node].c]==0){ ans++; color[tree[node].c]++; } return; } if (tree[node].l==tree[node].r) return; count(2*node); count(2*node+1); } void solve(int n,int t){ build(1,1,t); //cout<<"--------"<<endl; for (int i=1;i<=n;i++){ update(1,s[i].l,s[i].r,i); //cout<<"123456789\n"; } ans=0; memset(color,0,sizeof(color)); count(1); printf("%d\n",ans); } int main(){ int t,n; scanf("%d",&t); while (t--){ scanf("%d",&n); for (int i=1;i<=n;i++){ scanf("%d%d",&s[i].l,&s[i].r); a[2*i-1].p=s[i].l; a[2*i-1].index=i; //标记为左端点 a[2*i].p=s[i].r; a[2*i].index=-i; //标记为右端点 } sort(a+1,a+2*n+1,cmp); //数据离散化 int t=1; int tmp=a[1].p; for (int i=1;i<=2*n;i++){ if (tmp!=a[i].p){ tmp=a[i].p; t++; } if (a[i].index>0) s[a[i].index].l=t; else s[-a[i].index].r=t; } /* for (int i=1;i<=n;i++){ printf("%d %d\n",s[i].l,s[i].r); } */ solve(n,t); } return 0; }
n(n<=10000)个人依次贴海报,给出每张海报所贴的范围li,ri(1<=li<=ri<=10000000)。
求出最后还能看见多少张海报。
相关文章推荐
- Stream groupings中可以选择的组别及含义
- 【算法学习笔记】69. 枚举法 字典序处理 SJTU OJ 1047 The Clocks
- HDU 3277 Marriage Match III
- iOS:苹果企业证书通过网页分发安装app
- 6.2-6
- PAT 1036 Boys vs Girls
- 设计模式读书笔记:Facade(外观)
- ios设置按钮点击时的文字和图片(而非非背景)
- C++中重载与重写函数区别及虚函数
- 37.两个链表的第一个公共结点
- C++ STL中的vector的内存分配与释放
- 包的完整定义
- C/C++浮点数在内存中的存储方式
- cocos2dx 编写shader 遇到 溢出问题
- MyBatis初级
- ArcGIS Engine标注(Label)
- Alcatraz在xcode安装无效的解决方案
- Android手机安全卫士(二)---设置、自定义控件属性、md5加密、手机防盗
- C++在struct与class差异
- Java -- 使用阻塞队列(BlockingQueue)控制线程通信