poj1436 Horizontally Visible Segments

这是一个区间更新的题目,先将区间放大两倍,至于为什么要放大可以这样解释,按照从左到右有4个区间,y值是[1,5],[1,2],[3,4],[1,4]如果不放大的话,查询[1,4]区间和前面区间的”可见“情况时,由于[1,2],[2,3]将2,3端点覆盖,最终得不到[1,5]和区间[1,4]”可见“的情况,而实际上两者的[2,3]区间是可以存在一条水平线将其直接相连的。接下来将要更新的区间按照x从小到大排序,然后依次查询,查询之后再更新就行。

这样可以得到一个描述各个区间的相互关系的图G[N],G[i]存储的是在区间i右边的”可见“的区间,最后暴力统计一下,就可以解决问题了。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<vector>
  5 #define lson l,m,rt<<1
  6 #define rson m+1,r,rt<<1|1
  7 #define M (1<<15)
  8 #define maxn 16000
  9 #define N 8001
 10 
 11 using namespace std;
 12 
 13 typedef struct
 14 {
 15     int x,s,e;
 16 } Seg;
 17 
 18 Seg seg[N];
 19 int color[M],Hash[N];/*color[rt]为-1表示区间没有完全覆盖,0和其他整数表示被相应的sticks完全覆盖,*/
 20 int n;
 21 
 22 vector<int>G[N];
 23 
 24 int cmp(Seg a,Seg b)
 25 {
 26     return a.x<b.x;
 27 }
 28 
 29 void PushDown(int rt)
 30 {
 31     if(color[rt]!=-1)
 32     {
 33         color[rt<<1]=color[rt<<1|1]=color[rt];
 34         color[rt]=-1;
 35     }
 36 }
 37 
 38 void update(int L,int R,int c,int l,int r,int rt)
 39 {
 40     if(L<=l&&R>=r)
 41     {
 42         color[rt]=c;
 43         return;
 44     }
 45     PushDown(rt);
 46     int m=(l+r)>>1;
 47     if(L<=m)
 48         update(L,R,c,lson);
 49     if(R>m)
 50         update(L,R,c,rson);
 51 }
 52 
 53 void query(int L,int R,int c,int l,int r,int rt)
 54 {
 55     if(color[rt]!=-1)
 56     {
 57         if(Hash[color[rt]]!=color[rt])
 58         {
 59             Hash[color[rt]]=color[rt];
 60             G[color[rt]].push_back(c);
 61         }
 62         return;
 63     }
 64     int m=(l+r)>>1;
 65     if(L<=m)
 66         query(L,R,c,lson);
 67     if(R>m)
 68         query(L,R,c,rson);
 69 }
 70 
 71 int main()
 72 {
 73     int tc;
 74     scanf("%d",&tc);
 75     while(tc--)
 76     {
 77         memset(color,0,sizeof(color));
 78         scanf("%d",&n);
 79         for(int i=1; i<=n; i++)
 80         {
 81             scanf("%d%d%d",&seg[i].s,&seg[i].e,&seg[i].x);
 82             seg[i].s<<=1;
 83             seg[i].e<<=1;
 84             G[i].clear();
 85         }
 86         sort(seg+1,seg+n+1,cmp);
 87         for(int i=1; i<=n; i++)
 88         {
 89             memset(Hash,0,sizeof(Hash));
 90             int l=seg[i].s;
 91             int r=seg[i].e;
 92             query(l,r,i,0,maxn,1);
 93             update(l,r,i,0,maxn,1);
 94         }
 95         int cnt=0;
 96         for(int i=1; i<=n; i++)
 97         {
 98             for(int j=0; j<G[i].size(); j++)
 99             {
100                 int k=G[i][j];
101                 for(int x=0; x<G[i].size(); x++)
102                     for(int w=0; w<G[k].size(); w++)
103                         if(G[k][w]==G[i][x])
104                             cnt++;
105             }
106         }
107         printf("%d
",cnt);
108     }
109     return 0;
110 }
原文地址:https://www.cnblogs.com/rootial/p/3246522.html