转载自http://www.cnblogs.com/CheeseZH/archive/2012/04/29/2476134.html
刚开始看到题目,想用memmove偷懒,结果TLE,后来查了查,才发现用memmove也是O(n^2)的复杂度。。。
#include <stdio.h> #include <string.h> int seq[222222]; int main() { int n,i,j,idx,posi,vali,t; while (~scanf("%d",&t)) { memset(seq,0,sizeof(seq)); for (i=0;i<t;i++) { scanf("%d%d",&posi,&vali); memmove(seq+posi+2,seq+posi+1,sizeof(int)*((i+1)-(posi+1))); seq[posi+1]=vali; } for (i=1;i<=t;i++) printf("%d ",seq[i]); printf("\b\n"); } return 0; }
在网上找了AC代码,还是没怎么看懂。
就知道是逆序遍历的,线段树结点存储的是当前区域的空位置数量。
关键是update函数中的代码看的不是很懂。
void update(int p,int l,int r,int rt){
...
if(Tree[rt<<1]>=p){
update(p,lson);
}else{
p-=Tree[rt<<1];
update(p,rson);
}
}
=======================================
![](https://i-blog.csdnimg.cn/blog_migrate/f57f8994083e51dc9f50634d070c1007.jpeg)
初始状态
首先是插入3 69
1,4结点有4个位置,
1,2结点有2个位置,小于3,因此放到1,4结点右孩子,且1,4结点空位置减1
到了1,4右孩子后,只要找到第3-2=1个位置即可,而3,4结点的左孩子3,3含有1个空位置,1>=1,所以放到3,3位置了。
插入2 33
★关键是这里如何处理★
插入2 51
此时1,4的左孩子只有1个位置,1<2,所以只能放到1,4的右孩子3,4上
3,4的左孩子有0个位置,所以只能放在3,4的右孩子4,4上。
插入1 77
=======================================
//package hduCode;
import java.util.*;
import java.math.*;
public class Main
{
Scanner scan;
int pos, val;
final int maxn=200005;
int n, id;
int[] arr=new int[maxn<<2];
int[] num;
int[][] inarr;
public Main()
{
scan=new Scanner(System.in);
inarr=new int[maxn<<2][2];
num=new int[maxn<<2];
}
public void inputAndProcess()
{
while( scan.hasNext() )
{
n=scan.nextInt();
build(1, 1, n);
for(int i=1; i<=n; i++)
{
inarr[i][0]=scan.nextInt()+1;
inarr[i][1]=scan.nextInt();
}
for(int i=n; i>=1; i--)
{
update(1, 1, n, inarr[i][0]);
arr[id]=inarr[i][1];
}
System.out.print(arr[1]);
for(int i=2; i<=n; i++)
{
System.out.print(" "+arr[i]);
}
System.out.println();
}
}
public void build(int rt, int l, int r)
{
int mid=(l+r)/2;
num[rt]=r-l+1;
//System.out.println("rt="+rt);
if( l==r ) return;
build(rt*2, l, mid);
build(rt*2+1, mid+1, r);
}
public void update(int rt, int l, int r, int p)
{
int mid=(l+r)/2;
num[rt]--;
if( l==r )
{
id=l;
return;
}
if( num[rt<<1]>=p )
{
update(rt<<1, l, mid, p);
}else
{
p-=num[rt<<1];
update(rt<<1|1, mid+1, r, p);
}
}
public static void main(String[] args)
{
Main main=new Main();
main.inputAndProcess();
}
}