zoukankan      html  css  js  c++  java
  • poj 2481 Cows

    题意:

    输入若干个区间,对于一个区间(a,b),如果存在一个区间(x,y)满足x <= a && y >= b && y - x > b - a,那么就说(x,y)比(a,b)大。

    求比每一个区间大的区间有多少。

    思路:

    树状数组,这题最关键的其实是有重复的区间。

    首先把区间按照起点升序排序,如果起点相同,那么按照终点降序排序,这样的目的是为了先统计大区间。

    对于一个区间,如果这个区间和前面的区间重合,那么它的答案就是前一个区间的答案;

    若不重合,那么统计大于等于这个区间的终点的区间的个数,就是答案。

    为什么,因为前面的区间的起点大于等于它,并且终点大于等于它,并且不存在起点和终点都等于它的区间,因为重复的区间已经特殊处理了。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 using namespace std;
     5 const int N = 1e5 + 10;
     6 int len[N];
     7 struct node
     8 {
     9     int id;
    10     int s,e;
    11 } a[N];
    12 int mlen;
    13 int gg[N];
    14 bool cmp(node aa,node bb)
    15 {
    16     if (aa.s == bb.s) return aa.e > bb.e;
    17     return aa.s < bb.s;
    18 }
    19 int lowbit(int x)
    20 {
    21     return x&(-x);
    22 }
    23 void add(int x)
    24 {
    25     for (int i = x;i <= mlen;i += lowbit(i)) len[i] += 1;
    26 }
    27 int getsum(int x)
    28 {
    29     int ans = 0;
    30     for (int i = x;i > 0;i -= lowbit(i)) ans += len[i];
    31     return ans;
    32 }
    33 int main()
    34 {
    35     int n;
    36     while (scanf("%d",&n) != EOF && n)
    37     {
    38         mlen = 0;
    39         memset(len,0,sizeof(len));
    40         memset(gg,0,sizeof(gg));
    41         for (int i = 0;i < n;i++)
    42         {
    43             int x,y;
    44             scanf("%d%d",&x,&y);
    45             x++,y++;
    46             a[i].id = i;
    47             a[i].s = x;
    48             a[i].e = y;
    49             mlen = max(y,mlen);
    50         }
    51         sort(a,a+n,cmp);
    52         for (int i = 0;i < n;i++)
    53         {
    54             int x = a[i].s,y = a[i].e;
    55             if (i > 0 && x == a[i-1].s && y == a[i-1].e)
    56             {
    57                 gg[a[i].id] = gg[a[i-1].id];
    58                 add(y);
    59                 continue;
    60             }
    61             int tmp = getsum(y-1);
    62             tmp = i - tmp;
    63             gg[a[i].id] = tmp;
    64             add(y);
    65         }
    66         for (int i = 0;i < n;i++)
    67         {
    68             printf("%d%c",gg[i],i == n - 1 ? '
    ':' ');
    69         }
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    最小堆
    HDU1022+栈
    POJ2318+几何+判点在四边形内
    HDU1003+最大连续子序列和+起始终止位置
    HDU1174+三维点到直线距离
    HDU4517
    Two Phase Commit (2PC) [转]
    分布式系统领域经典论文翻译集 [转]银河里的星星
    每个程序员都应该知道的8个LINUX命令 [转]
    Google File System解析 [转]
  • 原文地址:https://www.cnblogs.com/kickit/p/9071164.html
Copyright © 2011-2022 走看看