zoukankan      html  css  js  c++  java
  • poj 3067 Japan 【树状数组】

    <题目链接>

    题目大意:

    有两个点集,这两个点集从上至下分别从1~n,1~m编号,现在给出n组数据,(x,y),表示左边点集编号为x的点与右边点集编号为y的点相连,现在要求计算这些线段的交点个数。

    解题分析:

    先将这些线段的x变量从小到大排序,若x相同,再将y从小到大排序。然后就可以直接遍历这些线段了,同时对y变量建一维树状数组,利用sum(m)-sum(node[i].y)可以很容易求出之前插入的所有线段的y值中,有多少线段的y值大于当前插入的y值,这一步相当于对排好序的线段的y值进行逆序数的求解,因为之前插入线段的x必然小于等于当前线段的x值,所以这些y值还大于node[i].y的线段必然会与当前线段产生一个交点。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 typedef long long ll;
     7 const int M =1e6+10;
     8 int n,m,k;
     9 int tr[M]; 
    10 struct NODE{
    11     int x,y;
    12     bool operator <(const NODE &tmp)const{    
    13         if(x==tmp.x)return y<tmp.y;
    14         else return x<tmp.x;
    15     }
    16 }node[M];
    17 inline int lowbit(int x){return x&(-x);}
    18 void add(int i,int val){
    19     while(i<=m){
    20         tr[i]+=val;
    21         i+=lowbit(i);
    22     }
    23 }
    24 int sum(int i){
    25     ll ans=0;
    26     while(i>0){
    27         ans+=tr[i];
    28         i-=lowbit(i);
    29     }
    30     return ans;
    31 }
    32 int main(){
    33     int T,ncase=0;
    34     scanf("%d",&T);
    35     while(T--){
    36         scanf("%d%d%d",&n,&m,&k);
    37         for(int i=1;i<=k;i++){
    38             scanf("%d%d",&node[i].x,&node[i].y);
    39         }
    40         sort(node+1,node+1+k);    
    41         memset(tr,0,sizeof(tr));
    42         ll ans=0;
    43         for(int i=1;i<=k;i++){
    44             ans+=sum(m)-sum(node[i].y);  //sum(m)表示之前插入所有线段的个数,sum(node[i],y)表示之前插入的所有y值小于等于node[i].y的线段个数,因此sum(m)-sum(node[i].y)求得的是之前插入的y值中,比当前node[i].y大的线段的个数
    45             //因为在该数之前插入树状数组的x值都小于等于当前线段的x值,所以这样可以求出所有线段相交的个数。
    46             add(node[i].y,1);
    47         }
    48         printf("Test case %d: %lld
    ",++ncase,ans);
    49     }
    50     return 0;
    51 }

    2018-10-17

  • 相关阅读:
    创建类以及引用一个类
    修改hosts文件
    微信第三方登录接口开发
    Android定位
    Leetcode 102. Binary Tree Level Order Traversal
    Leetcode 725. Split Linked List in Parts
    Leetcode 445. Add Two Numbers II
    Leetcode 328. Odd Even Linked List
    Leetcode 237. Delete Node in a Linked List
    Leetcode 234. Palindrome Linked List
  • 原文地址:https://www.cnblogs.com/00isok/p/9804155.html
Copyright © 2011-2022 走看看