HDU 5862(离散化+树状数组)

Problem Counting Intersections

题目大意

  给定n条水平或竖直的线段,统计所有线段的交点个数。 (n<=100000)

解题分析

  首先将线段离散化。

  然后将所有线段按照横坐标的顺序,按照先插入再查找再删除的顺序进行操作。

  对于横线 如果是左端点,则将其纵坐标加1,右端点则减1,对于竖线直接求和就行了。

参考程序

  1 #include 
  2 #include <set>
  3 #include 
  4 #include 
  5 #include 
  6 #include 
  7 #include <string>
  8 #include 
  9 #include 
 10 #include 
 11 #include 
 12 #include 
 13 #include 
 14 #include 
 15 #pragma comment(linker,"/STACK:102400000,102400000")
 16 using namespace std;
 17 
 18 #define N 100008             
 19 #define M 50008    
 20 #define LL long long
 21 #define lson l,m,rt<<1
 22 #define rson m+1,r,rt<<1|1 
 23 #define clr(x,v) memset(x,v,sizeof(x));
 24 #define rep(x,y,z) for (int x=y;x<=z;x++)
 25 #define repd(x,y,z) for (int x=y;x>=z;x--)
 26 const int mo  = 1000000007;
 27 const int inf = 0x3f3f3f3f;
 28 const int INF = 2000000000;
 29 /**************************************************************************/
 30 struct line{
 31     int x,y,z;
 32     line(int x=0,int y=0,int z=0):x(x),y(y),z(z){}
 33     bool operator <(const line b) const{
 34         return xb.z;
 35     }
 36 }a[N],b[N],c[N*2];
 37 
 38 int val[N*4],cnt;
 39 
 40 int id(int x){
 41     return lower_bound(val+1,val+cnt+1,x)-val;
 42 }
 43 
 44 struct Binary_Indexed_Tree{
 45     int a[N*5];
 46     void clear(){
 47         clr(a,0);
 48     }
 49     void insert(int x,int val){
 50         for (int i=x;i<=N<<2;i+=i & (-i))
 51             a[i]+=val;
 52     }
 53     int sigma(int x){
 54         int res=0;
 55         for (int i=x;i>0;i-=i & (-i))
 56             res+=a[i];
 57         return res;
 58     }
 59     int query(int x,int y){
 60         return sigma(y)-sigma(x-1);
 61     }
 62 }T;
 63 
 64 int main(){
 65     int testcase;
 66     scanf("%d",&testcase);
 67     while (testcase--){
 68         int n,na=0,nb=0,nc=0;
 69         cnt=0;
 70         scanf("%d",&n);
 71         rep(i,1,n){
 72             int x1,y1,x2,y2;
 73             scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
 74             val[++cnt]=x1;
 75             val[++cnt]=y1;
 76             val[++cnt]=x2;
 77             val[++cnt]=y2;
 78             if (x1==x2){
 79                 if (y1>y2) swap(y1,y2);
 80                 b[++nb]=line(x1,y1,y2);    
 81             }       
 82             if (y1==y2){
 83                 if (x1>x2) swap(x1,x2);
 84                 a[++na]=line(y1,x1,x2);
 85             }
 86         }
 87         sort(val+1,val+cnt+1);
 88         cnt=unique(val+1,val+cnt+1)-val-1;
 89         rep(i,1,na){
 90             a[i].x=id(a[i].x);
 91             a[i].y=id(a[i].y);
 92             a[i].z=id(a[i].z);
 93             c[++nc]=line(a[i].y,i,1);
 94             c[++nc]=line(a[i].z,i,3);
 95         }
 96         rep(i,1,nb){
 97             b[i].x=id(b[i].x);
 98             b[i].y=id(b[i].y);
 99             b[i].z=id(b[i].z);
100             c[++nc]=line(b[i].x,i,2);
101         }
102         sort(c+1,c+nc+1);
103         T.clear();
104         LL ans=0;
105         rep(i,1,nc){
106             if (c[i].z==1){
107                 T.insert(a[c[i].y].x,1);
108             }
109             if (c[i].z==2){
110                 ans+=T.query(b[c[i].y].y,b[c[i].y].z);
111             }
112             if (c[i].z==3){
113                 T.insert(a[c[i].y].x,-1);
114             }
115         }
116         printf("%lld\n",ans );
117     }
118 }
View Code

 

  

转载于:https://www.cnblogs.com/rpSebastian/p/5787346.html

你可能感兴趣的:(HDU 5862(离散化+树状数组))