给定墙的水平截面,以及从坐标 Xi 到 Yi 应用的 N 层油漆,输出可见的不同层数。
这是问题链接http://www.spoj.com/problems/POSTERS/
这是我的解决方案http://ideone.com/gBJKnL
方法:我尝试通过 Segment Tree 懒惰地更新子节点值来解决问题,最近的值在他们的懒惰更新中替换了旧的值。这样,只有最近的油漆被应用到水平横截面。尽管代码在自定义测试用例上运行良好,但它会占用大量内存并被在线法官中止。
#include <iostream>
#include <set>
#include <vector>
#define MAX 10000000+100
typedef long long int ll;
using namespace std;
ll Tree[3*MAX],lazy[MAX*2];
void Update(ll s,ll start,ll end,ll left,ll right,ll value)
{
if(lazy[s]!=0)
{
Tree[s]=(lazy[s]*(end-start+1));
if(start!=end)lazy[2*s+1]=lazy[s],lazy[s*2+2]=lazy[s];
lazy[s]=0;
}
if(start>end||left>end||right<start)return;
if(start>=left&&end<=right)
{
Tree[s] = (value*(end-start+1));
if(start!=end)
{
lazy[2*s+1]=value;
lazy[2*s+2]=value;
}
return ;
}
ll mid=(start+end)/2;
Update(2*s+1,start,mid,left,right,value);
Update(2*s+2,mid+1,end,left,right,value);
Tree[s] = Tree[s*2+1]+Tree[2*s+2];
}
ll Read(ll s,ll start,ll end,ll left,ll right)
{
if(start>end||start>right||end<left)return 0;
if(lazy[s]!=0)
{
Tree[s]=(lazy[s]*(end-start+1));
if(start!=end)
{
lazy[2*s+1]=lazy[s];
lazy[2*s+2]=lazy[s];
}
lazy[s]=0;
}
if(start>=left&&end<=right)return Tree[s];
else return (Read(2*s+1,start,(start+end)/2,left,right)+Read(2*s+2,1+((start+end)/2),end,left,right));
}
int main() {
// your code goes here
ll t;
cin>>t;
while(t--)
{
ll n,z=1,li=-1;
cin>>n;
vector<pair<ll,ll> > b;
for(ll i=0;i<n;i++)
{
ll u,v;
li = max(li,v);
cin>>u>>v;
b.push_back(make_pair(u-1,v-1));
}
for(auto v: b)
Update(0,0,li+2,v.first,v.second,z++);
set<ll> a;
for(ll i=0;i<li+2;i++)cout<<Read(0,0,li+2,i,i)<<" ",a.insert(Read(0,0,li+2,i,i));
cout<<endl;
cout<<a.size()-1<<endl;
}
return 0;
}