zoukankan      html  css  js  c++  java
  • CodeForces

    [CodeForces - 369E Valera and Queries](http://codeforces.com/problemset/problem/369/E) 题目大意:给出n个线段(线段的左端点和右端点坐标)和m个查询,每个查询有cnt个点,要求给出有多少条线段包含至少其中一个点。 思路:如果按照题意正面去算有每个线段是否包含点,那么时间复杂度是不允许的;如果去算每个点被哪些线段包含,那么去重比较困难。正难则反,因此对于每个查询,选择去求有多少个线段没有覆盖任何一个点,那么答案则为n减所求。用树状数组来统计没有覆盖任何一个点的线段数,大致做法是将临界线段(如x1+1,x2-1)插入seg数组中,再按一定规则进行排序,之后通过树状数组维护统计被包含于临界线段的线段数,具体实现在代码中。 代码: ```C++ #include #include #include 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.r0) { 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 ",ans[i]);
    }
    return 0;
    }

    </font>
  • 相关阅读:
    排序预处理的思想
    枚举
    math细节
    physics 衍射和ganshe
    hearing speaking words
    appium的环境安装
    基于ASP.NET MVC 4.0的音乐商店全套项目教程
    WPF/WinForm 关于窗体大小变化的消息机制处理
    用WPF搭建自己的万能播放器(C#)前篇
    VS2010网站发布到服务器上
  • 原文地址:https://www.cnblogs.com/orangee/p/9011050.html
Copyright © 2011-2022 走看看