T3:统计包含每个点的矩形数目
排序+二分
class Solution {
public:
vector<int> g[105];
vector<int> countRectangles(vector<vector<int>>& rectangles, vector<vector<int>>& points) {
for(auto u:rectangles){
g[u[1]].push_back(u[0]);
}
for(int i=0;i<=100;i++)
sort(g[i].begin(),g[i].end());
vector<int> res;
for(auto u:points){
int x=u[0],y=u[1];
int ans=0;
for(int i=y;i<=100;i++){
if(g[i].empty()) continue;
ans+=g[i].end()-lower_bound(g[i].begin(),g[i].end(),x);
}
res.push_back(ans);
}
return res;
}
};
树状数组+二维偏序
我们要注意一条性质,那就是对于点 p1,p2,
如果p2在p1的左下方那么包含 p1,p2的所有矩形,一定也包含 p2
在统计矩形数目的时候,可以将这种性质转化成一种前缀和关系
我们可以按照从上到下,从右到左的次序遍历所有的矩形和点
每一个矩形可看作是一次单点修改,每一个点就可以看作是一次前缀和查询
class Solution {
public:
#define N 50005
struct Node{int x,y,id;};
struct BIT
{
int len,t[N];
void init(int l){len=l,memset(t,0,sizeof(t));}
inline int lowbit(int x){return x&(-x);}
void update(int u,int v){for(int i=u;i<=len;i+=lowbit(i)) t[i]+=v;}
int query(int u)
{
int ans=0;
for(int i=u;i>0;i-=lowbit(i)) ans+=t[i];
return ans;
}
}bit;
Node a[N*2];
int ans[N];
vector<int> countRectangles(vector<vector<int>>& r, vector<vector<int>>& p) {
int n=r.size(),q=p.size();
for(int i=0;i<n;i++) a[i]=(Node){r[i][0],101-r[i][1],-1};
for(int i=0;i<q;i++) a[i+n]=(Node){p[i][0],101-p[i][1],i};
bit.init(100);
sort(a,a+n+q,[&](Node x,Node y){
if(x.x!=y.x) return x.x>y.x;
else return x.id<y.id;
});
for(int i=0;i<n+q;i++)
{
if(a[i].id==-1) bit.update(a[i].y,1);
else ans[a[i].id]=bit.query(a[i].y);
}
return vector<int>(ans,ans+q);
}
};
T4:花期内花的数目
差分
class Solution {
public:
vector<int> g[105];
vector<int> fullBloomFlowers(vector<vector<int>>& flowers, vector<int>& persons) {
map<int,int> mp;
for(int x:persons)
mp[x]=0;
for(vector<int>&a:flowers){
int l=a[0],r=a[1];
++mp[l]; --mp[r+1];
}
int pre=0;
for(auto &[k,v]:mp){
v+=pre;
pre=v;
}
vector<int> res;
for(int x:persons){
res.push_back(mp[x]);
}
return res;
}
};