http://codeforces.com/contest/286/problem/D
越是有难度的题目 解出来就越高兴
对于这个题,不知道其他人有没有简单解法,看了一下别人的代码 太多宏定义 太恶心了
自己憋了N久终于想出来一种解法,在各种WA和TLE之后终于过了
个人思路:
如果某一个地方已经有墙了 ,再出来墙,就没有意义了。以时间早的墙为准,对后出现的墙且和已经出现的墙重叠的部分进行处理(切掉)
这样最后就变成了一段段没有重叠的墙了 我处理的时候用的是优先队列,处理的时候要注意,否则会超时
假如说某些墙挡住了在时间a[i]出发的人 ,那么在a[i+1]出发的人也一定会被那些墙挡住,当然还可能另外多出一些墙可以挡住a[i+1]
利用这个性质,对根据时间出发的人的数组 用上面处理过的断进行处理(记录相关信息)
最后遍历更新一遍就可以了。
太乱了,没办法
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<algorithm>
//#define LL long long
//#define ULL unsigned long long
using namespace std;
const int INF=0x3f3f3f3f;
const int N=100010;
struct node1
{
int l,r,t;
const bool operator <(const node1 x)const
{
if(l==x.l)
return r<x.r;
return l>x.l;
}
};
priority_queue<node1>qt1;
int n,m;
int a[N],b[N],c[N],sum[N];
int binsearch(int l,int r,int k,int t)
{
while(l<=r)
{
int mid=(l+r)>>1;
if((t-a[mid])<k)
r=mid-1;
else
l=mid+1;
}
if(l>r)
swap(l,r);
if(l>0&&(t-a[l])<k)
{return l;}
return r;
}
void add(node1 x1)
{
int l=binsearch(1,n+1,x1.r,x1.t);
int r=binsearch(1,n+1,x1.l,x1.t);
if(l>=r)
{
c[r]+=(x1.r-x1.l+1);
}else
{
++b[l];
c[l]+=(x1.r-(x1.t-a[l]));
--b[r];
c[r]-=((x1.r-(x1.t-a[r])-(x1.r-x1.l+1)));
}
}
int main()
{
//freopen("data.in","r",stdin);
while(scanf("%d %d",&n,&m)!=EOF)
{
while(!qt1.empty())qt1.pop();
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
memset(sum,0,sizeof(sum));
node1 x1,y1,z1;
while(m--)
{
scanf("%d %d %d",&x1.l,&x1.r,&x1.t);
++x1.l;
qt1.push(x1);
}
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
a[n+1]=ceil(1e9);
x1=qt1.top();qt1.pop();
while(!qt1.empty())
{
y1=qt1.top();qt1.pop();
if(y1.l>x1.r)
{add(x1);x1=y1;continue;}
if(y1.t==x1.t)
{x1.r=max(x1.r,y1.r);continue;}
if(y1.t<x1.t)
{
if(x1.l==y1.l)
{
if(y1.r>=x1.r)
x1=y1;
else
{
z1.l=y1.r+1;
z1.r=x1.r;
z1.t=x1.t;
qt1.push(z1);
x1=y1;
}
continue;
}
if(y1.r>=x1.r)
{x1.r=y1.l-1;add(x1);x1=y1;}
else
{
z1.l=y1.r+1;
z1.r=x1.r;
z1.t=x1.t;
qt1.push(z1);
x1.r=y1.l-1;
add(x1);
x1=y1;
}
continue;
}
if(y1.t>x1.t)
{
if(y1.r<=x1.r)
continue;
else
{y1.l=x1.r+1;qt1.push(y1);}
continue;
}
}
add(x1);
for(int i=1;i<=n;++i)
{
sum[i]=sum[i-1]+(b[i-1]*(a[i]-a[i-1]))+c[i];
printf("%d\n",sum[i]);
b[i]+=b[i-1];
}
}
return 0;
}
浙公网安备 33010602011771号