CodeForces - 369E Valera and Queries (tree array)


CodeForces - 369E Valera and Queries
title gist: Given n line segments (the coordinates of the left and right endpoints of the line segment) and m queries, each query has cnt points, and it is required to give how many line segments contain at least one of the points.
Idea: If you calculate whether each line segment contains a point according to the meaning of the question, then the time complexity is not allowed; if you calculate which line segments each point contains, then it is more difficult to deduplicate. Difficulty is the opposite, so for each query, choose to find how many line segments do not cover any point, then the answer is n minus. Use a tree array to count the number of line segments that do not cover any point. The general approach is to insert critical line segments (such as x1+1, x2-1) into the seg array, and then sort according to certain rules, and then maintain statistics through the tree array The number of line segments included in the critical line segment, which is implemented in the code.
Code:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1000000+5;
struct segment
{
    int l,r,id;
};
bool cmp(const segment& a,const segment& b)
{
    if (a.l!=b.l)
        return a.l>b.l;
    if (a.r!=b.r)
        return a.r<b.r;
    return a.id<b.id;
}
segment seg[maxn];
int tree[maxn+5];
void add(int i,int x)
{
    while (i<=maxn)
    {
        tree[i]+=x;
        i+=i&-i;
    }
    return;
}
int sum(int i)
{
    int sum=0;
    while (i>0)
    {
        sum+=tree[i];
        i-=i&-i;
    }
    return sum;
}
int ans[maxn];

int main()
{
    int n,m,i,j;
    cin>>n>>m;
    for (i=0;i<n;++i)
    {
        scanf("%d%d",&seg[i].l,&seg[i].r);
        seg[i].id=0;
    }
    int cnt,x,pre,tt=n;
    for (i=1;i<=m;++i)
    {
        ans[i]=n;
        pre=0;
        scanf("%d",&cnt);
        for (j=0;j<cnt;++j)
        {
            scanf("%d",&x);
            if (pre+1<=x-1)
            {
                seg[tt].l=pre+1;
                seg[tt].r=x-1;
                seg[tt++].id=i;
            }
            pre=x;
        }
        seg[tt].l=pre+1;
        seg[tt].r=maxn;
        seg[tt++].id=i;
    }
    sort(seg,seg+tt,cmp);
    for (i=0;i<tt;++i)
    {
        if (seg[i].id)
        {
            ans[seg[i].id]-=sum(seg[i].r);      
        }
        else
        {
            add(seg[i].r,1);
        }
    }
    for (i=1;i<=m;++i)
    {
        printf("%d\n",ans[i]);
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325879135&siteId=291194637