题意:一个二维平面,三种操作,1.清空所有点,2.在(x,y)上加一种颜色(不是覆盖),3.查询区域1~x,y1~y2这个二维区域内有几种颜色
思路:考虑给每种颜色建一颗线段树,维护的是一段y(几行)内这种颜色出现的最小的x,查询:y1-y2内的最小值比x小,那么区域内有这种颜色。由于空间的限制,需要动态开点。还可以把坐标离散化。
#include<bits/stdc++.h> using namespace std; const int maxn=1.5e5+10; struct data { int l,r,num; }node[maxn*30]; int p[maxn][4],tot; int row,con,root[55],flag; vector<int> v1,v2; int newnode() { node[tot].num = 0x3f3f3f3f; node[tot].l = node[tot].r = -1; return tot++; } void up(int ny,int x,int y,int &cnt,int val) { if(cnt == -1) cnt = newnode(); node[cnt].num = min(node[cnt].num,val); if(x == y) return; int mid = (x+y) / 2; if(ny <= mid) up(ny,x,mid,node[cnt].l,val); else up(ny,mid+1,y,node[cnt].r,val); } void fid(int qx,int qy,int x,int y,int cnt,int k) { if(flag) return; if((node[cnt].l == -1 && node[cnt].r == -1) || (qx == x && qy ==y)) { if(node[cnt].num <= k) flag = 1; return; } int mid = (x+y) / 2; if(qy <= mid) { if(node[cnt].l != -1) fid(qx,qy,x,mid,node[cnt].l,k); } else if(qx >= mid+1) { if(node[cnt].r != -1) fid(qx,qy,mid+1,y,node[cnt].r,k); } else { if(node[cnt].l != -1) fid(qx,mid,x,mid,node[cnt].l,k); if(node[cnt].r != -1) fid(mid+1,qy,mid+1,y,node[cnt].r,k); } } int qurey(int x2,int y1,int y2) { int num = 0; for(int i = 0; i <= 50; i++) { flag = 0; fid(y1,y2,1,row,root[i],x2); num += flag; } return num; } int main() { int op,t,en = 0; while(scanf("%d",&op)!=EOF && op != 3) { t = 1; if(op != 0) { p[1][0] = op; scanf("%d%d%d",&p[1][1],&p[1][2],&p[1][3]); t++; } while(scanf("%d",&op)!=EOF) { if(op == 3) { en = 1; break; } if(op != 0) { p[t][0] = op; scanf("%d%d%d",&p[t][1],&p[t][2],&p[t][3]); t++; } else break; } v1.clear(); v2.clear(); for(int i = 1; i < t; i++) { if(p[i][0] == 1) { v1.push_back(p[i][1]); v2.push_back(p[i][2]); } else { v1.push_back(p[i][1]); v2.push_back(p[i][2]); v2.push_back(p[i][3]); } } sort(v1.begin(),v1.end()); sort(v2.begin(),v2.end()); v1.erase(unique(v1.begin(),v1.end()),v1.end()); v2.erase(unique(v2.begin(),v2.end()),v2.end()); con = v1.size(); row = v2.size(); tot = 0; for(int i = 0; i <= 50; i++) { root[i] = newnode(); } for(int i = 1; i < t; i++) { if(p[i][0] == 1) { int x1 = lower_bound(v1.begin(),v1.end(),p[i][1]) - v1.begin() + 1; int y1 = lower_bound(v2.begin(),v2.end(),p[i][2]) - v2.begin() + 1; up(y1,1,row,root[p[i][3]],x1); } else { int x2 = lower_bound(v1.begin(),v1.end(),p[i][1]) - v1.begin() + 1; int y1 = lower_bound(v2.begin(),v2.end(),p[i][2]) - v2.begin() + 1; int y2 = lower_bound(v2.begin(),v2.end(),p[i][3]) - v2.begin() + 1; printf("%d\n",qurey(x2,y1,y2)); } } if(en) break; } return 0; }