看了大佬的博客:https://blog.csdn.net/chenquanwei_/article/details/79137969;
题意:给n个线段的左右端点,问每个线段包括多少线段;类似于https://blog.csdn.net/weixin_42754600/article/details/81914015;
把左右端点看成x,y坐标,先离散化一下,然后按照x降序,x相等y升序排列一下,计算每个点前面有多少个y坐标小于等于它就行了;
离散化就是把数据范围变小,但是不改变相对大小,比如(-1e9,0,1e9) 离散化以后是(1,2,3) ; 计算起来方便
线段树;
#include<cstdio>
#include<iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2e5+10;
int a[maxn],t[maxn<<2],y;
struct node{
int x,y,s,t;//x,y是左右区间,s是输入的顺序,t是包含多少线段
}no[maxn];
bool cmp1(node a,node b){
return a.x>b.x||(a.x==b.x&&a.y<b.y);
}
bool cmp2(node a,node b){
return a.s<b.s;
}
int query(int l,int r,int rt){
int ans = 0;
if(r <= y) ans+=t[rt];
else if(y < l) return 0;
else{
int mid = (l+r)>>1;
ans += query(l,mid,rt<<1);
ans += query(mid+1,r,rt<<1|1);
}
return ans;
}
void update(int l,int r,int rt){
if(l == r){
t[rt]++;
return;
}
int mid = (l+r)>>1;
if(y<=mid) update(l,mid,rt<<1);
else update(mid+1,r,rt<<1|1);
t[rt]++;
}
int main()
{
int n;
while(cin>>n){
int k = n;
memset(no,0,sizeof(no));
memset(a,0,sizeof(a));
memset(t,0,sizeof(t));
for(int i = 0;i < k;i++){
cin>>no[i].x>>a[i];
no[i].y = a[i];
no[i].s = i;
}
sort(a, a + n);
n = unique(a, a + n) - a;
for(int i = 0; i < k; i++)
no[i].y = lower_bound(a, a + n, no[i].y) - a+1;//离散化,加一是不要零,从一开始
sort(no,no+n,cmp1);
for(int i = 0; i < k; i++){
y = no[i].y;
no[i].t = query(0,maxn,1);//查询
update(0,maxn,1);//更新
}
sort(no,no+n,cmp2);
for(int i = 0; i < k; i++) cout<<no[i].t<<endl;
}
return 0;
}
树状数组:
#include<cstdio>
#include<iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2e5+10;
int a[maxn],t[maxn],y;
struct node{
int x,y,s,t;//x,y是左右区间,s是输入顺序,t是包含多少区间
}no[maxn];
bool cmp1(node a,node b){
return a.x>b.x||(a.x==b.x&&a.y<b.y);
}
bool cmp2(node a,node b){
return a.s<b.s;
}
int lowbit(int x){
return x&(-x);
}
int query(int x){
int ans = 0;
while(x){
ans += t[x];
x -= lowbit(x);
}
return ans;
}
void update(int x){
while(x<=maxn){
t[x]++;
x += lowbit(x);
}
return;
}
int main()
{
int n;
while(cin>>n){
int k = n;
memset(no,0,sizeof(no));
memset(a,0,sizeof(a));
memset(t,0,sizeof(t));
for(int i = 0;i < k;i++){
cin>>no[i].x>>a[i];
no[i].y = a[i];
no[i].s = i;
}
sort(a, a + n);
n = unique(a, a + n) - a;
for(int i = 0; i < k; i++)
no[i].y = lower_bound(a, a + n, no[i].y) - a+1;//离散化,加一是不要零,从一开始
sort(no,no+n,cmp1);
for(int i = 0; i < k; i++){
y = no[i].y;
no[i].t = query(y);//查询
update(y);//更新
}
sort(no,no+n,cmp2);
for(int i = 0; i < k; i++) cout<<no[i].t<<endl;
}
return 0;
}