这是一个区间更新的题目,先将区间放大两倍,至于为什么要放大可以这样解释,按照从左到右有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\n",cnt); 108 } 109 return 0; 110 }