D. Tourists 夜

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

  

原文地址:https://www.cnblogs.com/liulangye/p/2983302.html