This is a creation in Article, where the information may have evolved or changed.
Portal: Hdu 5193 Go to Moviesⅱ
Test instructions
There are n people standing in a row, everyone's height is hi. Every time someone joins or someone leaves, judge how many people are standing in the opposite (I < J&&HI>HJ)
First line n,m, next n integers (n,m<=2e4)
Next M line,
0 x y indicates that a person with a height of Y is inserted behind X, and x=0 is inserted at the front. (1≤y≤n)
1 x indicates that the first person (left to right) leaves.
Idea: excerpted from the http://bestcoder.hdu.edu.cn/solutions.php?page=12
When you add or remove an element, you need to know how much before it is larger than it, and how much smaller it is after it. There are subscript and weight values of two dimensions, which can be nested using two data structures. The n=20000, the scope is not big, the outer layer can use the sub-block maintenance subscript, so that when adding and deleting elements,
Also very convenient, direct violence. It is convenient to use a tree-like array when searching for the number of weights. The inner layer maintains a weighted value through a tree-like array. If the size of each block is S, then when deleting or adding elements, the complexity of maintaining the inverse logarithm is O (S+p∗logn), and S is the cost of direct violence in the block in reverse order.
P/s∗logn in the front block than it and in the back block to find a smaller price than it, p represents the number of current elements. In order to make the two parts of the complexity as far as possible to s=p/s∗logn,s take root Plogn
。 When added and removed directly by block violence, the size of the block degrades and needs to be refactored. The complexity of refactoring once is S*logn, and the total refactoring complexity is one to the total complexity of adding and removing. So the complexity of the whole problem is O (M√nlogn).
#include <bits/stdc++.#include <bits / stdc ++. h>
using namespace std;
const int maxn = 20010;
const int MAX_S = 1050;
int ans, tot, n;
void add (int * c, int x, int v) {
while (x <= n) {
c [x] + = v;
x + = (x & -x);
}
}
int sum (int * c, int x) {
int ret = 0;
while (x> 0) {
ret + = c [x];
x-= (x & -x);
}
return ret;
}
struct node_t {
int num [MAX_S + 10], sz, c [maxn], next, pre;
void init () {
memset (c, 0, sizeof (c));
sz = 0;
pre = 0;
next = 0;
}
} b [310];
int get_pos (int & x) {
int i = 1;
while (b [i] .sz <x && b [i] .next)
x- = b [i] .sz, i = b [i] .next;
return i;
}
int cal (int x) {
int ret = 0;
int id = get_pos (x);
for (int i = 1; i <x; i ++)
if (b [id] .num [i]> b [id] .num [x])
ret ++;
for (int i = x + 1; i <= b [id] .sz; i ++)
if (b [id] .num [i] <b [id] .num [x])
ret ++;
for (int i = 1; i! = id; i = b [i] .next)
ret + = sum (b [i] .c, n) -sum (b [i] .c, b [id] .num [x]);
for (int i = b [id] .next; i! = 0; i = b [i] .next)
ret + = sum (b [i] .c, b [id] .num [x] -1);
return ret;
}
int flag;
void ins (int x) {
int y = x;
if (flag == 0) {// is it the first element
b [1] .init ();
scanf ("% d", & b [1] .num [++ b [1] .sz]);
add (b [1] .c, b [1] .num [1], 1);
flag = 1;
return;
}
int id = get_pos (x); // id indicates in which block
if (b [id] .sz == MAX_S) {// block reconstruction
b [++ tot] .init (), b [id] .sz ++;
int cnt = 0;
for (int i = b [id] .sz; i> x; i--)
b [id] .num [i] = b [id] .num [i-1];
scanf ("% d", & b [id] .num [x]);
add (b [id] .c, b [id] .num [x], 1);
int len = b [id] .sz / 2;
for (int i = len + 1; i <= b [id] .sz; i ++) {
b [tot] .num [++ cnt] = b [id] .num [i];
add (b [tot] .c, b [id] .num [i], 1);
add (b [id] .c, b [id] .num [i],-1);
}
b [tot] .sz = cnt, b [tot] .next = b [id] .next;
b [id] .next = tot, b [id] .sz = len;
b [tot] .pre = id;
}
else {
b [id] .sz ++;
for (int i = b [id] .sz; i> x; i--)
b [id] .num [i] = b [id] .num [i-1];
scanf ("% d", & b [id] .num [x]);
add (b [id] .c, b [id] .num [x], 1);
}
ans + = cal (y);
}
void del (int x) {
ans- = cal (x);
int id = get_pos (x);
add (b [id] .c, b [id] .num [x],-1);
for (int i = x + 1; i <= b [id] .sz; i ++)
b [id] .num [i-1] = b [id] .num [i];
b [id] .sz--;
if (b [id] .sz == 0) {// delete block
int pre = b [id] .pre, net = b [id] .next;
b [net] .pre = pre;
b [pre] .next = net;
}
}
int main () {
int m, op, x, y;
while (~ scanf ("% d% d", & n, & m)) {
ans = 0, tot = 1, b [1] .sz = 0, flag = 0;
for (int i = 1; i <= n; i ++)
ins (i);
for (int i = 1; i <= m; i ++) {
scanf ("% d", & op);
if (op == 0) {
scanf ("% d", & x);
ins (x + 1);
}
else {
scanf ("% d", & x);
del (x);
}
printf ("% d \ n", ans);
}
}
return 0;
} h>using namespace Std;Const intmaxn=20010;Const intmax_s=1050;intAns,tot,n;voidAddint*c,intXintV) { while(x<=n) {c[x]+=v; x+= (x&-x); }}intSumint*c,intx) {intret=0; while(x>0) {ret+=c[x]; x-= (x&-x); }returnRET;}structnode_t{intnum[max_s+Ten],sz,c[maxn],next,pre;voidInit () {memset (c,0,sizeof(c)); sz=0; Pre=0; next=0; }}b[310];intGet_pos (int&X) {intI=1; while(B[i]. SZ<x&&b[i]. Next) X-=b[i]. SZ, I=b[i]. Next;returni;}intCalintx) {intret=0;int ID=get_pos (x); for(intI=1; i<x;i++)if(b[ID]. Num[i]>b[ID]. Num[x]) ret++; for(inti=x+1; i<=b[ID]. SZ; i++)if(b[ID]. Num[i]<b[ID]. Num[x]) ret++; for(intI=1; i!=ID; I=b[i]. Next) Ret+=sum (B[i]. C, N)-sum (B[i]. C, b[ID]. Num[x]); for(inti=b[ID]. Next; i!=0; I=b[i]. Next) Ret+=sum (B[i]. C, b[ID]. Num[x]-1);returnRET;}intFlagvoidInsintx) {intY=x;if(flag==0){//is not the first elementb[1]. Init(); scanf"%d", &b[1]. Num[++b[1]. SZ]); Add (b[1]. C, b[1]. Num[1],1); flag=1;return; }int ID=get_pos (x);where does the//id say if(b[ID]. SZ==max_s) {//Block refactoringB[++tot]. Init(), b[ID]. SZ++;intCnt=0; for(inti=b[ID]. SZ; i>x;i--) b[ID]. Num[i]=b[ID]. Num[I1]; scanf"%d", &b[ID]. Num[x]); Add (b[ID]. C, b[ID]. Num[x],1);intlen=b[ID]. SZ/2; for(inti=len+1; i<=b[ID]. SZ; i++) {B[tot]. Num[++cnt]=b[ID]. Num[i]; Add (B[tot]. C, b[ID]. Num[I],1); Add (b[ID]. C, b[ID]. Num[i],-1); } B[tot]. SZ=cnt,b[tot]. Next=b[ID]. Next; b[ID]. Next=tot,b[ID]. SZ=len; B[tot]. Pre=ID; }Else{b[ID]. SZ++; for(inti=b[ID]. SZ; i>x;i--) b[ID]. Num[i]=b[ID]. Num[I1]; scanf"%d", &b[ID]. Num[x]); Add (b[ID]. C, b[ID]. Num[x],1); } ans+=cal (y);}voidDelintx) {ans-=cal (x);int ID=get_pos (x); Add (b[ID]. C, b[ID]. Num[x],-1); for(inti=x+1; i<=b[ID]. SZ; i++) b[ID]. Num[I1]=b[ID]. Num[i]; b[ID]. SZ--;if(b[ID]. SZ==0){//Delete block intpre=b[ID]. Pre, net=b[ID]. Next; B[net]. Pre=pre; B[pre]. Next=net; }}intMain () {intM,op,x,y; while(~SCANF ("%d%d", &n,&m)) {ans=0, tot=1, b[1]. SZ=0, flag=0; for(intI=1; i<=n;i++) ins (i); for(intI=1; i<=m;i++) {scanf ("%d", &op);if(op==0) {scanf ("%d", &x); INS (x+1); }Else{scanf ("%d", &x); Del (x); } printf ("%d\n", ans); } }return 0;}