poj 1436 线段树 '三元组'个数

来源:互联网 发布:苹果怎么备份数据 编辑:程序博客网 时间:2024/06/05 06:31

题意:给你垂线段,求最多能找到多少三元组

解法:线段维护最新的阴影,并且建立关系

New point :所有的点乘以二进行维护

三元组的定义:任意两个垂线段可以相见,能够找到水平线连接两线段且不相交其他线段

对于插入的点都要乘以2,是因为对于[1,2],[3,4],对于线段[2,3]只能表示成分居两地的两个点,但是乘以二后,最小的线段长度=2,必然存在两个段

  1. /************************************************************************* 
  2.     > File Name: poj1436.cpp 
  3.     > Author: cy 
  4.     > Mail: 1002@qq.com  
  5.     > Created Time: 14/11/8 18:08:35 
  6.  ************************************************************************/ 
  7.  
  8. #include<iostream> 
  9. #include<cstring> 
  10. #include <algorithm> 
  11. #include<cstdlib> 
  12. #include<vector> 
  13. #include<cmath> 
  14. #include<stdlib.h> 
  15. #include<iomanip> 
  16. #include<list> 
  17. #include<deque> 
  18. #include<map> 
  19. #include <stdio.h> 
  20. #include <queue> 
  21.  
  22. #define maxn 8000+100 
  23.  
  24. #define inf 0x3f3f3f3f 
  25.   #define INF 0x3FFFFFFFFFFFFFFFLL 
  26. #define rep(i,n) for(i=0;i<n;i++) 
  27.  #define reP(i,n) for(i=1;i<=n;i++) 
  28.  
  29. #define ull unsigned long long 
  30.  #define ll long long 
  31.  
  32. #define cle(a) memset(a,0,sizeof(a)) 
  33. #define bug cout<<"____bug____" 
  34. using namespace std; 
  35. struct Edge{//可以连接的两个线段建边 
  36.     int to,next; 
  37. }edge[maxn*1000]; 
  38.  
  39. struct Tree{//线段树 
  40.     int l,r; 
  41.     int flag;//判断覆盖情况 
  42.     int mid(){ 
  43.         return (l+r)/2
  44.     } 
  45. }tree[80080]; 
  46.  
  47. struct Date{ 
  48.     int l,r,x; 
  49. }date[maxn]; 
  50. bool cmp(Date a,Date b){ 
  51.     return a.x<b.x; 
  52. int head[maxn];bool hash[maxn][maxn];int point[maxn]; 
  53. int num; 
  54. void init(){ 
  55.     memset(head,-1,sizeof(head)); 
  56.     cle(hash); 
  57.     num=0
  58. void add(int a,int b){ 
  59.     if(hash[a][b])return
  60.     edge[num].to=b,edge[num].next=head[a],head[a]=num++; 
  61.     hash[a][b]=hash[b][a]=true
  62. void build(int rt,int l,int r){//建立线段树 
  63.     tree[rt].l=l; 
  64.     tree[rt].r=r; 
  65.     tree[rt].flag=0
  66.     if(l==r)return
  67.     int mid=tree[rt].mid(); 
  68.     build(rt*2,l,mid); 
  69.     build(rt*2+1,mid+1,r); 
  70. void update(int rt,int l,int r,int ip){ 
  71.     if(tree[rt].l==l&&tree[rt].r==r&&tree[rt].flag!=-1){//可以进行更新操作 
  72.         add(tree[rt].flag,ip); 
  73.         tree[rt].flag=ip; 
  74.         return
  75.     } 
  76.     else
  77.         if(tree[rt].flag!=-1){ 
  78.             tree[rt<<1].flag=tree[rt].flag;tree[rt<<1|1].flag=tree[rt].flag;//向下更新 
  79.             tree[rt].flag=-1;//表示遇到这一段必须向下更新(找阴影) 
  80.         } 
  81.         int mid=tree[rt].mid(); 
  82.         if(r<=mid)update(rt<<1,l,r,ip); 
  83.         else if(l>mid)update(rt<<1|1,l,r,ip); 
  84.         else
  85.             update(rt<<1,l,mid,ip);update(rt<<1|1,mid+1,r,ip); 
  86.         } 
  87.     } 
  88. int main() 
  89. #ifndef ONLINE_JUDGE 
  90.      freopen("in.txt","r",stdin); 
  91.      //freopen("out.txt","w",stdout); 
  92. #endif 
  93.     int n,T;cin>>T; 
  94.     while(T--) 
  95.     { 
  96.         scanf("%d",&n); 
  97.         init(); 
  98.         int i,j,k; 
  99.         rep(i,n)scanf("%d%d%d",&date[i+1].l,&date[i+1].r,&date[i+1].x); 
  100.         sort(date+1,date+1+n,cmp); 
  101.         build(1,0,16000); 
  102.         rep(i,n){ 
  103.             int l=date[i+1].l,r=date[i+1].r; 
  104.             update(1,l*2,r*2,i+1); 
  105.         } 
  106.         int tail=0
  107.         int ans=0
  108.         for(i=1;i<=n;i++){ 
  109.             tail=0
  110.             for(j=head[i];j!=-1;j=edge[j].next){//这些线和i有阴影 
  111.                 point[tail++]=edge[j].to; 
  112.             } 
  113.             rep(j,tail){//找另外的两个满足的线段 
  114.                 for(k=j+1;k<tail;k++) 
  115.                 { 
  116.                     if(hash[point[j]][point[k]])ans++; 
  117.                 } 
  118.             } 
  119.         } 
  120.         cout<<ans<<endl; 
  121.     } 
  122.     return 0
  123. }
0 0
原创粉丝点击