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;

}

  

 

你可能感兴趣的:(uri)