UVA 11990(BIT套treap
题目:给出一个1到n的全排列,m个询问,每次删除一个数,输出此时总的逆序对数.
思路:树状数组每个节点都是treap,通过bit套treap来查询每个点前面有多少个比该点小的数...
思路还是比较简单的,但是写了挺长时间,现在一个很严重的缺点就是代码量一大就没有定力,然后直接gg.....以后要多写代码题尽力克服这个问题...
/* * @author: Cwind */ ///#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <queue> #include <stack> #include <functional> #include <set> #include <cmath> using namespace std; #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0) #define pb push_back #define PB pop_back #define bk back() #define fs first #define se second #define sq(x) (x)*(x) #define eps (3e-7) #define IINF (1<<29) #define LINF (1ll<<59) #define INF (1000000000) #define FINF (1e3) #define clr(x) memset((x),0,sizeof (x)); typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<int,int> P; const int MAXTREAPNODE=2e5*40; struct treapNode{ treapNode *ch[2]; int right,val; int sz; treapNode():sz(0){} int cmp(int x) const { if(x==val) return -1; return x>val; } void maintain(){ sz=ch[0]->sz+ch[1]->sz+1; } }pool[MAXTREAPNODE]; int ph; treapNode *null=new treapNode(); treapNode *newtreapNode(int v){ treapNode *n=&pool[ph++]; n->val=v; n->right=rand(); n->ch[0]=n->ch[1]=null; n->sz=0; return n; } struct Treap{ treapNode *root; void init(){ root=null; } void rotate(treapNode *&o,int d){ treapNode *k=o->ch[d^1]; o->ch[d^1]=k->ch[d]; k->ch[d]=o; o->maintain(); k->maintain(); o=k; } void insert(treapNode *&o,int x){ if(o==null) o=newtreapNode(x); else{ int d=o->val<x; insert(o->ch[d],x); if(o->ch[d]->right>o->right) rotate(o,d^1); } o->maintain(); } void insert(int x){insert(root,x);} void remove(treapNode *&o,int x){ int d=o->cmp(x); if(d==-1){ if(o->ch[0]==null) o=o->ch[1]; else if(o->ch[1]==null) o=o->ch[0]; else{ int d2=o->ch[0]->right>o->ch[1]->right; rotate(o,d2); remove(o->ch[d2],x); } }else remove(o->ch[d],x); if(o!=null) o->maintain(); } void remove(int x){remove(root,x);} int calless(treapNode *n,int x){ if(n==null) return 0; int ans=0; if(n->val<x){ ans+=n->ch[0]->sz+1; ans+=calless(n->ch[1],x); }else{ ans+=calless(n->ch[0],x); } return ans; } int cal(int x){return calless(root,x);} }; const int maxn=2e5+3000; struct BIT2{ int B[maxn]; void init(){clr(B);} int sum(int p){ int ans=0; while(p>0){ ans+=B[p]; p-=p&-p; } return ans; } void add(int p,int x){ while(p<maxn){ B[p]+=x; p+=p&-p; } } }A,cnt; struct BIT{ Treap B[maxn]; void init(){ for(int i=0;i<maxn;i++) B[i].init(); } void insert(int p,int a){ while(p<maxn){ B[p].insert(a); p+=p&-p; } } void delet(int p,int a){ while(p<maxn){ B[p].remove(a); p+=p&-p; } } int getless(int p,int x){ int ans=0; while(p>0){ ans+=B[p].cal(x); p-=p&-p; } return ans; } }B; int n,m; int sq[maxn]; int pos[maxn]; ll ans; void init(){ ph=0; ans=0; A.init();B.init();cnt.init(); } int main(){ freopen("/home/slyfc/CppFiles/in","r",stdin); //freopen("defense.in","r",stdin); //freopen("defense.out","w",stdout); while(cin>>n>>m){ init(); for(int i=1;i<=n;i++){ scanf("%d",&sq[i]); pos[sq[i]]=i; ans+=i-A.sum(sq[i])-1; A.add(sq[i],1); cnt.add(i,1); B.insert(i,sq[i]); } for(int i=0;i<m;i++){ cout<<ans<<endl; int x; scanf("%d",&x); int p=pos[x]; int tolless=A.sum(x)-1; int foreless=B.getless(p,x); int foretol=cnt.sum(p)-1; ans-=tolless-foreless; ans-=foretol-foreless; A.add(x,-1);cnt.add(p,-1); B.delet(p,x); } } return 0; }