本文主要是介绍poj2528 Mayor's posters 【线段树】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目难度还好只要知道流程了,代码基本能写出来
大致思路是:对所有区间的端点进行排序,并离散化节省空间时间
然后读入每一张海报,更新所表示的区间,最后统计能看得到多少张海报
比较坑的是,这题卡scanf,用c++交过的,载上一篇文章
https://www.byvoid.com/blog/fast-readfile C++中的快速读取
#include <map>
#include <set>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int n;
int z=0;//离散范围
//const int MXN=11111;
//int x[MXN],y[MXN],a[2*MXN],c[10*MXN];
int a[80010],c[80010],x[10010],y[10010];
map<int,int> mp;
set<int> st;
bool cmp(int a,int b)
{return a<b;
}
void build(int nodei,int l,int r)//重新构建,清零,因为有多组数据
{c[nodei]=0;if(l==r)return;int mid=(l+r)>>1;build(nodei*2,l,mid);build(nodei*2+1,mid+1,r);
}
void input()//输入,排序,离散化
{mp.clear();st.clear();z=0;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d",&x[i],&y[i]);a[i*2-1]=x[i];a[i*2]=y[i];}sort(a+1,a+2*n+1,cmp);int i=1;z=0;while(i<=2*n-1)//排序后建立离散映射{if(a[i]==a[i+1]){i++;continue;}mp[a[i]]=++z;i++;}//if(a[2*n-1]!=a[2*n])// mp[a[2*n]]=++z;//else// mp[a[2*n]]=++z;mp[a[2*n]]=++z;//等效build(1,1,z);
}
void update(int nodei,int l,int r,int L,int R,int No)//更新海报粘贴情况
{if(l==L&&r==R)//找到该区间{c[nodei]=No;return;}if(c[nodei])//如果该区间已经被贴了海报,那么将该区间的情况转移到子区间,比如1-6已经贴上了3号的海报,我要更新的是4-7贴的是4号的海报,那么把1-6情况下放为1-3 4-6两个子结点,更改右结点情况即可,而且1-6这个结点要清零,因为后来我们是通过插入每个结点的值到集合来维护有多少张海报的,比如刚才那个情况,搜索到1-6为3就不搜索了,而事实是只有1-3贴的是3号,而4-6贴的是4号{c[nodei*2+1]=c[nodei*2]=c[nodei];c[nodei]=0;}int mid=(L+R)>>1;//对该区间下的左右子区间继续进行更新直到更新好对应的区间的结点if(mid>=r)update(nodei*2,l,r,L,mid,No);else if(mid<l)update(nodei*2+1,l,r,mid+1,R,No);else{update(nodei*2,l,mid,L,mid,No);update(nodei*2+1,mid+1,r,mid+1,R,No);}
}
void dfs(int nodei,int l,int r)//搜索每个结点,如果不为0则说明这里贴了海报,把他们插入集合,最后集合的元素个数就是海报的张数
{if(c[nodei]){st.insert(c[nodei]);return;}if(l==r)return;int mid=(l+r)>>1;dfs(nodei*2,l,mid);dfs(nodei*2+1,mid+1,r);
}
void work()//逐章更新所有海报的张贴情况,并得出结果
{for(int i=1;i<=n;i++){update(1,mp[x[i]],mp[y[i]],1,z,i);}dfs(1,1,z);printf("%d\n",st.size());
}
int main()
{#ifndef ONLINE_JUDGEfreopen("G:/1.txt","r",stdin);freopen("G:/2my.txt","w",stdout);#endifint T;scanf("%d",&T);while(T--){input();work();}return 0;
}
这篇关于poj2528 Mayor's posters 【线段树】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!