询问一个区间内包含多少个别的区间,这个好像用动态开点更方便(我不会),主要方法就是如果遇到的是之前没见过的点,就开一个点,如果是之前出现过的点,就统计这点之后的已经出现的点即可
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+10;
typedef struct G{
int l,r,cnt;
}G;
int w[N],p[N];
G tr[N];
void pushup(G &a,G &b,G &c)
{
a.cnt=b.cnt+c.cnt;
}
void pushup(int v)
{
pushup(tr[v],tr[v<<1],tr[v<<1|1]);
}
void build(int v,int l,int r)
{
tr[v]={l,r,0};
if(l==r)return ;
int mid=l+r>>1;
build(v<<1,l,mid);
build(v<<1|1,mid+1,r);
}
void mes(int v,int l)
{
//cout<<l<<" "<<tr[v].l<<" "<<tr[v].r<<"\n";
if(tr[v].l==l&&tr[v].r==l)
{tr[v].cnt=1;
return ;
}
int mid=tr[v].l+tr[v].r>>1;
if(mid>=l)mes(v<<1,l);
else mes(v<<1|1,l);
pushup(v);
}
int que(int v,int l,int r)
{
if(tr[v].l>r)return 0;
if(tr[v].r<l)return 0;
if(tr[v].l>=l&&tr[v].r<=r)return tr[v].cnt;
int cnt=0;
int mid=tr[v].l+tr[v].r>>1;
// cout<<mid<<" "<<l<<" "<<r<<"\n";
if(mid>=l)cnt+=que(v<<1,l,r);
if(mid<r)cnt+=que(v<<1|1,l,r);
return cnt;
}
signed main ()
{
int n,cnt=0;
cin>>n;
build(1,1,n);
for(int i=0;i<2*n;i++)cin>>w[i];
map<int,int>m;
for(int i=0;i<2*n;i++)
{
if(!m[w[i]]){
m[w[i]]=++cnt;
continue;
}
else {
// cout<<"????\n";
p[w[i]]=que(1,m[w[i]],cnt);
mes(1,m[w[i]]);
}
}
for(int i=1;i<=n;i++)cout<<p[i]<<" ";
}