lightoj 1089 【离散化+线段树】

题意:
给你n个区间,然后给你m个i点问你这个点在几个所给定的区间里;
思路:

离散化+区间覆盖

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5e4+10;

struct SegT{
    int left,right;
    int val;
    int flag;
};
SegT q[N*12];
int n,Q;
int arr[N*4];

void Build(int num,int L,int R)
{
    q[num].left=L;
    q[num].right=R;
    q[num].flag=q[num].val=0;
    if(L==R)
        return;
    int mid=(L+R)/2;
    Build(2*num, L,mid);
    Build(2*num+1,mid+1,R);
}

void Pushdown(int num)
{
    if(q[num].flag)
    {
        q[2*num].val+=(q[2*num].right-q[2*num].left+1)*q[num].flag;
        q[2*num+1].val+=(q[2*num+1].right-q[2*num+1].left+1)*q[num].flag;
        q[2*num].flag+=q[num].flag;
        q[2*num+1].flag+=q[num].flag;
        q[num].flag=0;
    }
}

void Update(int num,int s,int t)
{
    if(q[num].left>=s&&q[num].right<=t)
    {
        q[num].flag+=1;
        q[num].val+=(q[num].right-q[num].left+1);       //wa在了这里。。只要加1就行了,无奈给乘了。。。q[num].flag...不过还是有长进///
        return;
    }
    Pushdown(num);
    int mid=(q[num].left+q[num].right)/2;
    if(mid>=t)
        Update(2*num,s,t);
    else if(mid<s)
        Update(2*num+1,s,t);
    else
    {
        Update(2*num,s,mid);
        Update(2*num+1,mid+1,t);
    }
    q[num].val=q[2*num].val+q[2*num+1].val;
}

int query(int num,int id)
{
    if(q[num].left==id&&q[num].left==q[num].right)
        return q[num].val;
    Pushdown(num);
    int mid=(q[num].right+q[num].left)/2;
    if(mid>=id)
        return query(2*num,id);
    else
        return query(2*num+1,id);
}

vector<int>xs;
int main()
{
    int T,cas=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&Q);
        xs.clear();
        for(int i=1;i<=2*n;i+=2)
        {
            scanf("%d%d",&arr[i],&arr[i+1]);
            xs.push_back(arr[i]);
            xs.push_back(arr[i+1]);
        }
        for(int i=1;i<=Q;i++)
        {
            scanf("%d",&arr[i+2*n]);
            xs.push_back(arr[i+2*n]);
        }
        int num=0;
        sort(xs.begin(),xs.end());
        vector<int>::iterator e=unique(xs.begin(),xs.end());
        for(int i=1;i<=2*n+Q;i++)
        {
            arr[i]=lower_bound(xs.begin(),e,arr[i])-xs.begin()+1;
            num=max(num,arr[i]);
        }
        Build(1,1,num);
        
        for(int i=1;i<=2*n;i+=2)
            Update(1,arr[i],arr[i+1]);

        printf("Case %d:\n",cas++);
        for(int i=1;i<=Q;i++)
            printf("%d\n",query(1,arr[i+2*n]));
    }
    return 0;
}

/*
5 4
6 12
8 8
10 12
8 11
0 12
11
12
2
20

3 3
1 3
2 4
5 6
1
2
3
*/



posted @ 2016-11-19 11:00  see_you_later  阅读(135)  评论(0编辑  收藏  举报