CDQ分治
#include<bits/stdc++.h>
#define RG register
#define IL inline
#define _ 200005
using namespace std;
IL int gi(){
RG int data = 0 , m = 1; RG char ch = 0;
while(ch != '-' && (ch<'0'||ch>'9'))ch = getchar();
if(ch == '-'){m = -1; ch = getchar();}
while('0'<=ch && ch<='9')
data = (data<<3) + (data<<1) + (ch - '0') , ch = getchar();
return (m) ? data : -data;
}
int tot,bt[_],n,k,f[_],g[_],blg[_]; long long ans[_];
struct Node{
int a, b, c , w , id;
//w记录这个节点对应多少个真实节点,id则是其对应编号.
bool operator <(const Node &B)const{
return (b == B.b) ? c <= B.c : b < B.b;}
};
Node q1[_],q[_],tmp[_];
namespace BIT{
IL void Update(RG int ps,RG int dt){
for(RG int i = ps; i <= k; i += (i&-i))bt[i] += dt;
}
IL void Clear(RG int ps){
for(RG int i = ps; i <= k; i += (i&-i))bt[i] = 0;
}
IL int Query(RG int ps){
RG int res = 0;
for(RG int i = ps; i > 0; i -= (i&-i))res += bt[i];
return res;
}
}
void cdq(RG int L,RG int R){
if(L == R)return;
RG int mid = (L+R)>>1; cdq(L,mid); cdq(mid+1,R);
RG int l = L , r = mid+1 , oo = L-1;
while(l <= mid && r <= R){
if(q[l] < q[r])
BIT::Update(q[l].c,q[l].w) ,
tmp[++oo] = q[l++];
else
g[q[r].id] += BIT::Query(q[r].c) ,
tmp[++oo] = q[r++];
}
while(l <= mid)tmp[++oo] = q[l++];
while(r <= R)
g[q[r].id] += BIT::Query(q[r].c) ,
tmp[++oo] = q[r++];
for(RG int i = L; i <= R; i ++)
BIT::Clear(tmp[i].c) , q[i] = tmp[i];
return;
}
IL bool cmp(Node a,Node b){
if(a.a != b.a)return a.a < b.a;
if(a.b != b.b)return a.b < b.b;
if(a.c != b.c)return a.c < b.c;
return a.id < b.id; //注意:这里一定要随便定义一个优先级
}
IL bool Equl(int nw,int cp){
if(!cp)return false;
else return (q1[nw].a==q[cp].a &&
q1[nw].b==q[cp].b && q1[nw].c==q[cp].c);
}
int main(){
n = gi(); k = gi();
for(RG int i = 1,a,b,c; i <= n; i ++)
a = gi(),b = gi(),c = gi(),
q1[i] = (Node){a , b , c , 1 , i};
//去重:
tot = 0;
sort(q1+1,q1+n+1,cmp);
for(RG int i = 1; i <= n; i ++){
if(!Equl(i,tot))
q[++tot] = q1[i] , q[tot].w = 1 , q[tot].id = tot;
else q[tot].w ++;
blg[i] = tot; //记录i点是对应去重后的哪个节点
}
cdq(1,tot);
// f[i] 表示去重前点i满足 (aj<=ai,bj<=bi,cj<=ci) 的j的个数.
// g[i] 表示去重后点i满足条件的j的个数
for(RG int i = 1; i <= tot; i ++)g[q[i].id] += q[i].w-1;
for(RG int i = 1; i <= n; i ++)f[i] = g[blg[i]];
for(RG int i = 1; i <= n; i ++)ans[f[i]] ++;
for(RG int i = 0; i < n; i ++)printf("%lld\n",ans[i]);
return 0;
}
#include<bits/stdc++.h>
#define RG register
#define IL inline
#define _ 300005
using namespace std;
IL int gi(){
RG int data = 0 , m = 1; RG char ch = 0;
while(ch != '-' && (ch<'0'||ch>'9'))ch = getchar();
if(ch == '-'){m = -1; ch = getchar();}
while('0'<=ch && ch<='9')
data = (data<<3) + (data<<1) + (ch - '0') , ch = getchar();
return (m) ? data : -data;
}
struct Query{
int tm , ps , val;
bool operator < (const Query &B)const{ return ps < B.ps; }
};
Query q[_] , tmp[_];
int ans[_],bt[_],n,m,pos[_]; long long Ans; bool vis[_];
namespace BIT{
IL void Update(RG int ps,RG int dt){
for(RG int i = ps; i <= n; i += (i&-i))bt[i] += dt;
}
IL int Query(RG int ps){
RG int res = 0;
for(RG int i = ps; i > 0; i -= (i&-i))res += bt[i];
return res;
}
}
void cdq(RG int L,RG int R){
if(L == R)return;
RG int mid = (L+R)>>1; cdq(L,mid); cdq(mid+1,R);
RG int l = L , r = mid+1 , oo = L-1;
while(l<=mid && r<=R)
if(q[l] < q[r])tmp[++oo] = q[l++]; else tmp[++oo] = q[r++];
while(l<=mid)tmp[++oo] = q[l++];
while(r<=R)tmp[++oo] = q[r++];
for(RG int i = L; i <= R; i ++)q[i] = tmp[i];
//get - behind - smaller
for(RG int i = L; i <= R; i ++)
if(q[i].tm <= mid)BIT::Update(q[i].val,1);
else ans[q[i].tm] += BIT::Query(n) - BIT::Query(q[i].val);
for(RG int i = L; i <= R; i ++)
if(q[i].tm <= mid)BIT::Update(q[i].val,-1);
//get - front - bigger
for(RG int i = R; i >= L; i --)
if(q[i].tm <= mid)BIT::Update(q[i].val,1);
else ans[q[i].tm] += BIT::Query(q[i].val);
for(RG int i = R; i >= L; i --)
if(q[i].tm <= mid)BIT::Update(q[i].val,-1);
return;
}
IL bool cmp(Query a,Query b){return a.tm<b.tm;}
int main(){
n = gi(); m = gi();
RG int tot = 0;
for(RG int u,i = 1; i <= n; i ++)
u = gi() , pos[u] = i , vis[u] = 1;
for(RG int u,i = n; i >= n-m+1; i --)
u = gi() , vis[u] = 0 ,
q[++tot] = (Query){i,pos[u],u};
RG int cnt = n - m + 1;
for(RG int i = 1; i <= n; i ++)
if(vis[i])q[++tot] = (Query){--cnt,pos[i],i};
sort(q+1,q+tot+1,cmp);
cdq(1,tot);
Ans = 0;
for(RG int i = 1; i <= n; i ++)Ans += ans[i];
for(RG int i = n; i >= n-m+1; i --)
printf("%lld\n",Ans) , Ans -= ans[i];
return 0;
}
#include<bits/stdc++.h>
#define RG register
#define IL inline
#define ll long long
#define _ 4*500005
using namespace std;
int n,m,ask,tot; ll ans[_];
struct Do{
int typ,pos,val;
bool operator <(const Do &B)const{
return (pos == B.pos)?typ < B.typ : pos < B.pos; }
};
Do q[_],tmp[_];
void cdq(RG int L,RG int R){
if(L == R)return;
RG int mid = (L+R)>>1; cdq(L,mid); cdq(mid+1,R);
RG ll upt = 0 , l = L , r = mid+1 , oo = 0;
while(l <= mid && r <= R){
if(q[l] < q[r]){
if(q[l].typ == 1)upt += q[l].val;
tmp[++oo] = q[l++];
}
else {
if(q[r].typ == 2)ans[q[r].val] -= upt;
if(q[r].typ == 3)ans[q[r].val] += upt;
tmp[++oo] = q[r++];
}
}
while(l <= mid){
if(q[l].typ == 1)upt += q[l].val;
tmp[++oo] = q[l++];
}
while(r <= R){
if(q[r].typ == 2)ans[q[r].val] -= upt;
if(q[r].typ == 3)ans[q[r].val] += upt;
tmp[++oo] = q[r++];
}
for(RG int i = L; i <= R; i ++)q[i] = tmp[i-L+1];
}
int main(){
scanf("%d %d",&n,&m);
for(RG int i = 1,ww; i <= n; i ++)
scanf("%d",&ww), q[++tot] = (Do){1,i,ww};
ask = 0;
for(RG int i = 1,tp,ps,ww; i <= m; i ++){
scanf("%d %d %d",&tp,&ps,&ww);
if(tp == 1)q[++tot] = (Do){1,ps,ww};
else
q[++tot] = (Do){2,ps-1,++ask} ,
q[++tot] = (Do){3,ww,ask};
}
cdq(1,tot);
for(RG int i = 1; i <= ask; i ++)cout<<ans[i]<<endl;
return 0;
}