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; }