POJ 2528
题意:铺海报,问最后能看到几种海报
做法:原来做过的题,也写过博客。然而离散化还是不太会啊,大神的的离散化太巧妙了!
for(int i=1;i<=m;++i)
{
scanf("%d%d",&x[i],&y[i]);
hash[++cnt]=x[i];
hash[++cnt]=y[i];
}
sort(hash+1,hash+1+cnt);
int num=1;
for(int i= 2;i<=cnt;++i)
{
if(hash[num]!=hash[i]) hash[++num]=hash[i];
}
for(int i=num; i>=0;--i)
{
if(hash[i]-hash[i-1]>1) hash[++num]=hash[i]-1;
}
sort(hash+1,hash+1+num);
二分:
int bsearch(int l,int r,int x)
{
int m;
while(l<=r)
{
int m=(l+r)>>1;
if(hash[m]==x) return m;
else if(hash[m]>x) r=m-1;
else l=m+1;
}
return l;
}
ZOJ 1610
题意:每次将[L,R]端点覆盖,问最后每个颜色有多少个连续的子段(如果没有则不输出)
做法:模拟覆盖,最后统计的时候,每次记录一下前一个点的颜色即可
注意:这里的L,R都是端点,其实覆盖的是[L+1,R]这个大区间,其中每个节点表示长度为1的小区间
还有一个坑点:L,R范围不确定,直接上8000把
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#define lson rt<<1,begin,mid
#define rson rt<<1|1,mid+1,end
using namespace std;
const int maxn=8000;
int tree[maxn*4 +5];
int ans[maxn*4 +5];
int pre;
void pushdown(int rt)
{
if(tree[rt]!=-1)
{
tree[rt<<1] = tree[rt<<1|1] = tree[rt];
tree[rt] = -1;
}
}
void updata(int rt,int begin,int end,int l,int r,int x)
{
if(begin>=l&&r>=end)
{
tree[rt] = x;
return ;
}
pushdown(rt);
int mid=(begin+end)>>1;
if(mid>=l) updata(lson,l,r,x);
if(r>mid) updata(rson,l,r,x);
}
void querry(int rt,int begin,int end)
{
if(begin==end)
{
if(tree[rt]>=0&&tree[rt]!=pre)
{
ans[tree[rt]]++;
}
pre=tree[rt]; return;
}
pushdown(rt);
int mid=(begin+end)>>1;
querry(lson); querry(rson);
}
int main()
{
int m;
while(scanf("%d",&m)!=EOF)
{
memset(tree,-1,sizeof(tree));
memset(ans,0,sizeof(ans));
for(int i=1;i<=m;++i)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(b>a)updata(1,1,8000,a+1,b,c);
}
pre=-1;
querry(1,1,8000);
for(int i=0;i<=8000;++i)
{
if(ans[i])
{
printf("%d %d\n",i,ans[i]);
}
}
printf("\n");
}
return 0;
}