大型网站系统架构,vue做公司网站,建站行业前景怎么样,北京企业网站备案正题
题目链接:https://www.luogu.com.cn/problem/P3157 题目大意
一个长度为nnn序列#xff0c;每次删除一个数#xff0c;求删除前的逆序对数量。 解题思路
时光倒流之后#xff0c;我们变为每次加入一个数求逆序对数量。
我们将加入一个数的贡献分为后面和前面两部分…正题
题目链接:https://www.luogu.com.cn/problem/P3157 题目大意
一个长度为nnn序列每次删除一个数求删除前的逆序对数量。 解题思路
时光倒流之后我们变为每次加入一个数求逆序对数量。
我们将加入一个数的贡献分为后面和前面两部分 后面是加入时后方比他小的数的个数 前面是加入时前方比他大的数的个数
这里用aia_iai表示加入的时间先后bib_ibi表示位置cic_ici表示数值
若只考虑后方我们可以发现加入xxx时iii有贡献当且仅当 [ai≤axbibxcicx][a_i\leq a_x\ \\ b_ib_x\ \\ c_ic_x][ai≤ax bibx cicx]
然后可以发现这是一个三维偏序问题我们用CDQCDQCDQ树状数组维护。
做两次分别计算前后的贡献就可以了
时间复杂度O(nlog2n)O(n\log^2 n)O(nlog2n) codecodecode
#includecstdio
#includecstring
#includealgorithm
#define ll long long
using namespace std;
const ll N1e510;
struct node{ll a,b,c;
}a[N];
ll n,m,ans[N],loc[N];
struct Tree_Array{#define lowbit(x) (x-x)ll t[N];void Change(ll x,ll z){while(xn){t[x]z;xlowbit(x);}}ll Ask(ll x){ll ans0;while(x){anst[x];x-lowbit(x);}return ans;}#undef lowbit(x)
}T;
bool cmp_a(node x,node y){if(x.a!y.a) return x.ay.a;return (x.by.b)?(x.cy.c):(x.by.b);
}
bool cmp_zb(node x,node y)
{return (x.by.b)?(x.cy.c):(x.by.b);}
bool cmp_fb(node x,node y)
{return (x.by.b)?(x.cy.c):(x.by.b);}
void Cdq(ll l,ll r){if(lr) return;ll mid(lr)1;Cdq(l,mid);Cdq(mid1,r);sort(al,amid1,cmp_zb);sort(amid1,ar1,cmp_zb);ll kl;for(ll imid1;ir;i){while(kmida[k].ba[i].b)T.Change(a[k].c,1),k;ans[a[i].a]T.Ask(a[i].c);}for(ll il;ik;i)T.Change(a[i].c,-1);return;
}
void Cdp(ll l,ll r){if(lr) return;ll mid(lr)1;Cdp(l,mid);Cdp(mid1,r);sort(al,amid1,cmp_fb);sort(amid1,ar1,cmp_fb);ll kl;for(ll imid1;ir;i){while(kmida[k].ba[i].b)T.Change(n-a[k].c1,1),k;ans[a[i].a]T.Ask(n-a[i].c1);}for(ll il;ik;i)T.Change(n-a[i].c1,-1);return;
}
int main()
{scanf(%lld%lld,n,m);for(ll i1;in;i)scanf(%lld,a[i].c),a[i].bi,loc[a[i].c]i,a[i].bn-a[i].b1;for(ll i1,x;im;i)scanf(%lld,x),a[loc[x]].am-i;sort(a1,a1n,cmp_a);Cdq(1,n);sort(a1,a1n,cmp_a);Cdp(1,n);for(ll i1;im;i)ans[i]ans[i-1];for(ll im-1;i0;i--)printf(%lld\n,ans[i]);
}