您的位置:首页 > 其它

HDU 5193 块状链表求带插入删除操作的全局逆序对数

2017-08-05 22:07 441 查看
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define maxn 20010
#define maxlim 150
using namespace std;
inline void read(int &x) {
char ch;
bool flag = false;
for (ch = getchar(); !isdigit(ch); ch = getchar())if (ch == '-') flag = true;
for (x = 0; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
x = flag ? -x : x;
}
inline void write(int x) {
static const int maxlen = 100;
static char s[maxlen];
if (x < 0) {   putchar('-'); x = -x;}
if (!x) { putchar('0'); return; }
int len = 0; for (; x; x /= 10) s[len++] = x % 10 + '0';
for (int i = len - 1; i >= 0; --i) putchar(s[i]);
}

int lim;
int block[2*maxlim][2*maxlim];
int siz[maxlim] , cnt;
int pree[2*maxlim],nextt[2*maxlim];
int n,m;
int tree[2*maxlim][maxn];
int ans=0;

int get_pos(int &x){
int now=1;
while (  ( siz[now]<x) && ( nextt[now] ) )
{
x-=siz[now];
now=nextt[now];
}
return  now;
}

int lowbit(int x){
return x & (-x);
}

void add(int pos,int x,int op){
while (x<=n)
{
tree[pos][x]+=op;
x+=lowbit(x);
}
}

int query(int pos,int x){
int tmp=0;
while (x)
{
tmp+=tree[pos][x];
x-=lowbit(x);
}
return tmp;
}

void build(int a,int b){
pree[b]=a;  nextt[a]=b;
}

void rebuild(int x){
memset(tree[x],0,sizeof (tree[x]));
for (int i=1;i<=siz[x];i++)
add( x , block[x][i] ,1);
}

void calc(int at_block,int v,int at_in,int op){
int tmp=at_block;
while ( pree[tmp] )
{
tmp=pree[tmp];
ans+=( siz[tmp]-query(tmp,v) )*op;
}

tmp=at_block;
while ( nextt[tmp] )
{
tmp=nextt[tmp];
ans+=query( tmp ,v-1 )*op;

}
for (int i=1;i<=at_in;i++)
if (block[ at_block ][i]>v)
ans+=op;
for (int i=at_in+1;i<=siz[ at_block ];i++)
if (block[ at_block ][i]<v)
ans+=op;
}

void watch(){
for (int i=1;i;i=nextt[i])
{
printf("val= ");
for (int j=1;j<=siz[ i ];j++)
printf(" %d ",block[i][j] );
puts("");
}
}

void ins(int pos,int v){
int at_block=get_pos(pos);

calc(at_block,v,pos,1);

add(at_block , v ,1);

memmove(block[at_block]+pos+2,block[at_block]+pos+1,  sizeof(int)*(siz[ at_block ]-pos)  );
block[ at_block ][ pos+1 ]=v;
siz[ at_block ]++;

if (siz[at_block]>=2*lim)
{
++cnt;
build(cnt,nextt[at_block ] );
build(at_block ,cnt);
siz[cnt]=lim;
siz[at_block]=lim;
memcpy(block[cnt]+1,block[at_block]+lim+1,sizeof(int)*lim);
rebuild(at_block );
rebuild(cnt);
}

}

void Delete(int pos){
int at_block=get_pos(pos);

calc(at_block, block[ at_block ][ pos ] ,pos,-1);

add(at_block, block[ at_block ][ pos ] ,-1);

memmove(block[at_block]+pos,block[at_block ]+pos+1,  sizeof(int)*(siz[at_block]-pos)  );
siz[ at_block ]--;
if (siz[at_block]==0)
{
if (at_block!=1)
build(pree[at_block],nextt[at_block]);
}
}

int main(){
while (scanf("%d%d",&n,&m)!=EOF)
{
cnt=1;
pree[1]=0; nextt[1]=0;
siz[1]=0;
lim=sqrt(n);
ans=0;
for (int i=1;i<=n;i++)
{
int x;
read(x);
ins( i-1 , x);
}
for (int i=1;i<=m;i++)
{
int op;
read(op);
if (op==0)
{
int x,pos;
read(pos); read(x);
ins(pos,x);
printf("%d\n",ans);
}
else
{
int x;
read(x);
Delete(x);
printf("%d\n",ans);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐