您的位置:首页 > 其它

CodeForces 589G 线段树

2016-02-18 21:40 351 查看
题意:给一个数组,要求1到k的连续区间中大于d的元素与d之差值,的和大于等于r,求k的最小值,即对应的最小下标。

代码执行思路:

将不同的访问按限制d从小到大排序,则后面的元素可以继承前面的使用,节省时间。

开一个线段树,节点保存元素:sum(区间和),min(区间最小值),max(区间最大值),cap(区间有效元素数量)。

1,当d<=min时,取sum-d*cap。2,d>=max时,删除该区间。中间多搞几次二分,并且注意对于sum的运算要用long long,即可ac,具体实现看代码。

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<iostream>

using namespace std;

const int maxn=2e5+300;

const int INF=0x3f3f3f3f;

int N,M,T,D,R,ans[maxn];

struct node

{

    int l,r,minn,maxx,del,cap;

    long long sum;

}p[maxn<<2];

struct person

{

    int d,r,id;

    bool operator <(const person &b)const

    {

        return d<b.d;

    }

}pp[maxn];

void creat_tree(int l,int r,int q)

{

    p[q].l=l,p[q].r=r,p[q].sum=0;

    p[q].del=0,p[q].minn=INF,p[q].maxx=-INF;

    p[q].cap=(r-l+1);

    if(l==r)return;

    int m=(l+r)>>1;

    creat_tree(l,m,q<<1);

    creat_tree(m+1,r,q<<1|1);

}

void dele(int q)

{

    p[q].del=1,p[q].sum=0,

    p[q].minn=INF,p[q].maxx=-INF,p[q].cap=0;

    return;

}

void push_down(int q)

{

    if(p[q].l!=p[q].r&&p[q].del==1)

    {

        dele(q<<1);

        dele(q<<1|1);

    }

    return;

}

void push_up(int q)

{

    if(p[q].l!=p[q].r)

    {

        p[q].sum=p[q<<1].sum+p[q<<1|1].sum;

        p[q].minn=min(p[q<<1].minn,p[q<<1|1].minn);

        p[q].maxx=max(p[q<<1].maxx,p[q<<1|1].maxx);

        p[q].cap=p[q<<1].cap+p[q<<1|1].cap;

        if(p[q<<1].del==1&&p[q<<1|1].del==1)dele(q);

    }

    return;

}

void insert(int val,int po,int q)

{

    if(p[q].l==p[q].r)

    {

        p[q].sum=val;

        p[q].minn=val;

        p[q].maxx=val;

        p[q].cap=1;

        return;

    }

    int m=(p[q].l+p[q].r)>>1;

    if(po<=m)

       insert(val,po,q<<1);

    else

       insert(val,po,q<<1|1);

    push_up(q);

    return;

}

long long query(int l,int r,int d,int q)

{

    push_down(q);

    if(l>p[q].r||r<p[q].l||p[q].del==1)return 0;

    if(l<=p[q].l&&r>=p[q].r&&d>=p[q].maxx)

    {

        dele(q);

        push_down(q);

        return 0;

    }

    if(l<=p[q].l&&r>=p[q].r&&d<=p[q].minn)

    {

        return p[q].sum-(long long)d*p[q].cap;

    }

    long long ta= query(l,r,d,q<<1)+query(l,r,d,q<<1|1);

    push_up(q);

    return ta;

}

int search(int di,int ri)

{

    if(query(1,M,di,1)<ri)return 0;

    int l=1,r=M+1,m,an;

    while(l<r)

    {

        m=(l+r)/2;

        if(query(1,m,di,1)>=ri)

        {

            an=m;

            r=m;

        }

        else l=m+1;

    }

    return an;

}

int main()

{

    //freopen("a.txt","r",stdin);

    //int hh=1e10,jj=1e10;

    //cout<<hh*jj<<endl;

    while(~scanf("%d%d",&N,&M))

    {

        creat_tree(1,M,1);

        for(int i=1;i<=M;i++)

        {

            scanf("%d",&T);

            insert(T,i,1);

        }

        for(int i=1;i<=N;i++)

        {

            scanf("%d%d",&D,&R);

            pp[i].d=D,pp[i].r=R,pp[i].id=i;

        }

        sort(pp+1,pp+1+N);

        for(int i=1;i<=N;i++)

        {

            ans[pp[i].id]=search(pp[i].d,pp[i].r);

        }

        for(int i=1;i<=N;i++)

        {

            printf("%d",ans[i]);

            if(i<N)printf(" ");

            else printf("\n");

        }

    }

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: