poj 1436 线段树
题意:给你N条线段(垂直于x轴)的两个y坐标还有x坐标,问相互看到的三元组有多少个。
有点纠结就是,如果两个连线之间正好有一条线段的某个端点,这个也是不能计算的,所以这个端点就有意义了,所以就用上面那个题的做法,全部扩大二倍再用线段树。
Sample Input
1 //测试次数
5 //线段数目
0 4 4 //y1,y2,x
0 3 1
3 4 2
0 2 2
0 2 3
Sample Output
1
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f3f3f3f; 11 const double eps=1e-5; 12 #define cl(a) memset(a,0,sizeof(a)) 13 #define ts printf("*****\n"); 14 #define lson l,mid,rt<<1 15 #define rson mid+1,r,rt<<1|1 16 #define root 1,n,1 17 #define mid ((l+r)>>1) 18 const int MAXN=20000; 19 int n,m,t,Min,tt; 20 int sum[MAXN<<2],col[MAXN<<2],hash[MAXN]; 21 22 vector<int> v[MAXN]; 23 struct node 24 { 25 int s,t,x; 26 void in() 27 { 28 scanf("%d%d%d",&s,&t,&x); 29 s<<=1,t<<=1; 30 } 31 }a[MAXN]; 32 bool cmp(node A,node B) 33 { 34 return A.x<B.x; 35 } 36 void pushdown(int rt) 37 { 38 if(col[rt]!=-1) 39 { 40 col[rt<<1]=col[rt<<1|1]=col[rt]; 41 col[rt]=-1; 42 } 43 } 44 void update(int L,int R,int val,int l,int r,int rt) 45 { 46 if(l>=L&&r<=R) 47 { 48 col[rt]=val; 49 return; 50 } 51 pushdown(rt); 52 if(L<=mid) update(L,R,val,lson); 53 if(R>mid) update(L,R,val,rson); 54 } 55 void query(int L,int R,int val,int l,int r,int rt){ 56 if(col[rt]!=-1){ 57 if(hash[col[rt]]!=val){ //防止重复覆盖 58 v[col[rt]].push_back(val); 59 hash[col[rt]]=val; 60 } 61 return ; 62 } 63 if(l==r) return ; 64 pushdown(rt); 65 if(L<=mid) query(L,R,val,lson); 66 if(R>mid) query(L,R,val,rson); 67 } 68 int main() 69 { 70 int i,j,k; 71 #ifndef ONLINE_JUDGE 72 freopen("1.in","r",stdin); 73 #endif 74 scanf("%d",&tt); 75 while(tt--) 76 { 77 memset(col,-1,sizeof(col)); 78 memset(hash,-1,sizeof(hash)); 79 scanf("%d",&n); 80 for(i=0;i<n;i++) 81 { 82 a[i].in(); 83 v[i].clear(); 84 } 85 sort(a,a+n,cmp); 86 for(i=0;i<n;i++) 87 { 88 query(a[i].s,a[i].t,i,0,16000,1); 89 update(a[i].s,a[i].t,i,0,16000,1); 90 } 91 for(i=0;i<n;i++) 92 { 93 sort(v[i].begin(), v[i].end()); //v[i]储存的是i号结点所能看到的线段编号 94 } 95 int tot=0; 96 for(i=0;i<n;i++) 97 { 98 int len=v[i].size(); 99 for(j=0;j<len;j++) 100 { 101 for(k=j+1;k<len;k++) 102 { 103 int a1=v[i][j]; 104 int a2=v[i][k]; 105 if(binary_search(v[a1].begin(),v[a1].end(),a2)) tot++; 106 } 107 } 108 } 109 printf("%d\n",tot); 110 } 111 }