既是我第一个线段树套平衡树,也是一个比朴素还慢的树套树,不解释了 {$inline+} program syj; const maxn=20005; var z,nn,m,n,i,j,k,k1,k2,k3,ans,x,y,ll,rr,tt:longint; a,b,c,s:array[0..maxn]of longint; aux,l,r,son,p:array[0..32*maxn]of longint; rt:array[0..4*maxn]of longint; procedure sort(l,r:longint); var i,j,z:longint; begin i:=l;j:=r;a[0]:=a[b[(l+r)>>1]]; repeat while a[b[i]]<a[0] do inc(i); while a[b[j]]>a[0] do dec(j); if i<=j then begin z:=b[i];b[i]:=b[j];b[j]:=z; inc(i);dec(j); end; until i>j; if l<j then sort(l,j); if i<r then sort(i,r); end; procedure left(var i:longint); inline; var j:longint; begin j:=r[i];r[i]:=l[j];l[j]:=i; son[i]:=son[l[i]]+son[r[i]]+1; son[j]:=son[l[j]]+son[r[j]]+1; i:=j; end; procedure right(var i:longint); inline; var j:longint; begin j:=l[i];l[i]:=r[j];r[j]:=i; son[i]:=son[l[i]]+son[r[i]]+1; son[j]:=son[l[j]]+son[r[j]]+1; i:=j; end; procedure insert(var i:longint;k:longint); inline; begin if i=0 then begin inc(tt);i:=tt;p[i]:=k; aux[i]:=random(maxlongint); son[i]:=1; end else if (a[k]<a[p[i]])or(a[k]=a[p[i]])and(k<p[i]) then begin insert(l[i],k); inc(son[i]); if aux[l[i]]>aux[i] then right(i); end else begin insert(r[i],k); inc(son[i]); if aux[r[i]]>aux[i] then left(i); end; end; procedure delete(var i:longint;k:longint); inline; begin if p[i]=k then begin if l[i]=0 then i:=r[i] else if r[i]=0 then i:=l[i] else if aux[l[i]]>aux[r[i]] then begin right(i); delete(r[i],k); dec(son[i]); end else begin left(i); delete(l[i],k); dec(son[i]); end end else if (a[k]<a[p[i]])or(a[k]=a[p[i]])and(k<p[i]) then begin delete(l[i],k); dec(son[i]); end else begin delete(r[i],k); dec(son[i]); end; end; function rank(i,k:longint):longint; inline; begin if i=0 then exit(0); if a[p[i]]<=k then rank:=son[l[i]]+1+rank(r[i],k) else rank:=rank(l[i],k); end; procedure build(i,l,r:longint); inline; var m:longint; begin for j:=l to r do insert(rt[i],j); if l=r then exit; m:=(l+r)>>1; build(i*2,l,m);build(i*2+1,m+1,r); end; procedure ins(i,l,r,k:longint); inline; var m:longint; begin insert(rt[i],k); if l=r then exit; m:=(l+r)>>1; if k<=m then ins(i*2,l,m,k) else ins(i*2+1,m+1,r,k); end; procedure del(i,l,r,k:longint); inline; var m:longint; begin delete(rt[i],k); if l=r then exit; m:=(l+r)>>1; if k<=m then del(i*2,l,m,k) else del(i*2+1,m+1,r,k); end; function ask(i,l,r,p1,p2:longint):longint; inline; var m:longint; begin if (x<=l)and(r<=y) then ask:=rank(rt[i],p2)-rank(rt[i],p1) else begin m:=(l+r)>>1; ask:=0; if m>=x then ask:=ask(i*2,l,m,p1,p2); if m+1<=y then ask:=ask+ask(i*2+1,m+1,r,p1,p2); end; end; function find(i,j,p1,p2:longint):longint; inline; begin x:=i;y:=j; find:=ask(1,1,n,p1,p2); end; begin assign(input,'queue.in');reset(input); assign(output,'queue.out');rewrite(output); readln(n); for i:=1 to n do read(a[i]); for i:=1 to n do b[i]:=i; sort(1,n); a[0]:=0; for i:=1 to n do c[b[i]]:=c[b[i-1]]+ord(a[b[i]]<>a[b[i-1]]); nn:=c[b[n]]; for i:=1 to n do begin j:=c[i]+1; while j<=nn do begin inc(ans,s[j]); j:=j+j and-j; end; j:=c[i]; while j>0 do begin inc(s[j]); j:=j-j and-j; end; end; writeln(ans); build(1,1,n); readln(m); for m:=1 to m do begin readln(i,j); if a[i]=a[j] then begin writeln(ans); continue; end; if i>j then begin z:=i;i:=j;j:=z; end; if a[i]<a[j] then begin z:=1;ll:=a[i];rr:=a[j];inc(ans); end else begin z:=-1;ll:=a[j];rr:=a[i];dec(ans); end; k1:=find(i+1,j-1,ll,rr-1); k2:=find(i+1,j-1,ll-1,ll); k3:=find(i+1,j-1,rr-1,rr); inc(ans,(k1*2+k2+k3)*z); writeln(ans); del(1,1,n,i); del(1,1,n,j); z:=a[i];a[i]:=a[j];a[j]:=z; ins(1,1,n,i); ins(1,1,n,j); end; close(input);close(output); end. 不过这个程序竟然没用一个小时就敲出来了,小小的惊喜了一下