关闭

Codeforces Round #216_div2_E.Valera and Queries

标签: codeforces解题报告ACM369ECF
821人阅读 评论(0) 收藏 举报
分类:

转载注明出处  http://blog.csdn.net/moedane

 

 

传送门 http://codeforces.com/contest/369/problem/E

 

题意

给出n条线段,以及m个询问,每个询问包括cnt个点,问有多少条线段覆盖了至少一个点。

 

思路

我一开始是正着思考,想着怎样直接统计出覆盖的线段就好了。这样想的话要解决一个重复的问题,即一个线段覆盖了多个点。想直接用前缀和后缀和处理,但是样例都没法过,发现有许多问题。最后去看了别人代码才知道解法。

 

对每个询问,找出一个点都不覆盖的线段的数目。

要找出一个点都不覆盖的线段,方法是,用结构体存储询问的当前点和它左边的点,把落在该区域内的线段数目统计出来即可。对于每个询问,最左端端点可设为0,最右端可设为10^6,即问题转化为求落在这些区间内的线段的数目。

至于求这些线段数目的方法,是限制右端点小于当前询问的右端点,左端点则更新到树状数组中,即可找到当前区间内的线段数目。

先将线段排好序,离线处理询问。

 

代码

 

#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <cctype>
#define bug puts("here");

using namespace std;

typedef long long ll;

const int maxn = 3 * 100086;
const int mod = 1000000007;
const double PI = atan(1.0)*4.0;

int f[1000086];
int Ans[maxn];

struct Node
{
    int l,r,index;
}s[maxn],q[maxn*2];

bool cmp(Node a,Node b)
{
    return a.r < b.r;
}

int lowbit(int x)
{
    return x&(-x);
}

void update(int p,int v)
{
    while(p < 1000006)
    {
        f[p] += v;
        p += lowbit(p);
    }
    return;
}

int sum(int p)
{
    int ans = 0;
    while(p)
    {
        ans += f[p];
        p -= lowbit(p);
    }
    return ans;
}

int main()
{
    int m,n;
    scanf("%d%d",&n,&m);
    int i,j;
    for(i=0;i<n;i++)
        scanf("%d%d",&s[i].l,&s[i].r);
    int e = 0;
    for(i=0;i<m;i++)
    {
        int cnt;
        scanf("%d",&cnt);
        for(j=0;j<cnt;j++)
        {
            scanf("%d",&q[e].r);
            q[e].index = i;
            if(j == 0) q[e].l = 0;
            else q[e].l = q[e-1].r;
            e++;
        }
        q[e].index = i;
        q[e].l = q[e-1].r;
        q[e++].r = 1000006;
    }
    sort(s,s+n,cmp);
    sort(q,q+e,cmp);
    for(i=0;i<m;i++) Ans[i] = n;
    memset(f,0,sizeof(f));
    j = 0;
    for(i=0;i<e;i++)
    {
        while(j < n && s[j].r < q[i].r)
        {
            update(s[j].l,1);
            j++;
        }
        Ans[q[i].index] -= sum(q[i].r - 1) - sum(q[i].l);
    }
    for(i=0;i<m;i++) printf("%d\n",Ans[i]);
    return 0;
}


 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:7438次
    • 积分:177
    • 等级:
    • 排名:千里之外
    • 原创:11篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条