[BZOJ3295][CQOI2011]动态逆序对 树套树

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3295

观察可得,每一次答案减少的就是,这个数之前比它大的数的个数,这个数之后比它小的数的个数。

所以我们用树状数组来确保这个数前后的区间查询,用权值线段树求其代表的一个区间内比$x$大或小的数的个数。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 int inline readint(){
 7     int Num;char ch;
 8     while((ch=getchar())<'0'||ch>'9');Num=ch-'0';
 9     while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0';
10     return Num;
11 }
12 void outll(ll x){
13     if(x>=10) outll(x/10);
14     putchar(x%10+'0');
15 }
16 int N,M;
17 int pos[100010];
18 int inline lowbit(int &x){
19     return x&-x;
20 }
21 int Rt[100010],lc[10000000],rc[10000000],num[10000000],cnt=0;
22 void Insert(int &rt,int l,int r,int x){
23     if(!rt) rt=++cnt;
24     num[rt]++;
25     if(l==r) return;
26     int mid=l+r>>1;
27     if(x<=mid) Insert(lc[rt],l,mid,x);
28     else Insert(rc[rt],mid+1,r,x);
29 }
30 int Qry(int &rt,int l,int r,int L,int R){
31     if(!rt) return 0;
32     if(l>=L&&r<=R) return num[rt];
33     int mid=l+r>>1,ret=0;
34     if(L<=mid) ret=Qry(lc[rt],l,mid,L,R);
35     if(R>mid) ret+=Qry(rc[rt],mid+1,r,L,R);
36     return ret;
37 }
38 void Del(int &rt,int l,int r,int x){
39     if(!rt) return;
40     num[rt]--;
41     if(l==r) return;
42     int mid=l+r>>1;
43     if(x<=mid) Del(lc[rt],l,mid,x);
44     else Del(rc[rt],mid+1,r,x);
45 }
46 ll Ans=0;
47 int main(){
48     N=readint();
49     M=readint();
50     for(int i=1;i<=N;i++){
51         int x=readint();
52         pos[x]=i;
53         for(int j=i;j<=N;j+=lowbit(j))
54             Insert(Rt[j],1,N,x);
55         if(x!=N)
56             for(int j=i;j>=1;j-=lowbit(j))
57                 Ans+=Qry(Rt[j],1,N,x+1,N);
58     }
59     for(int i=1;i<=M;i++){
60         outll(Ans);
61         putchar('\n');
62         int x=readint();
63         if(x!=N)
64             for(int j=pos[x];j>=1;j-=lowbit(j))
65                 Ans-=Qry(Rt[j],1,N,x+1,N);
66         if(x!=1){
67             for(int j=N;j>=1;j-=lowbit(j))
68                 Ans-=Qry(Rt[j],1,N,1,x-1);
69             for(int j=pos[x]-1;j>=1;j-=lowbit(j))
70                 Ans+=Qry(Rt[j],1,N,1,x-1);
71         }
72         for(int j=pos[x];j<=N;j+=lowbit(j))
73             Del(Rt[j],1,N,x);
74     }
75     return 0;
76 }

 

posted @ 2017-10-14 11:25  halfrot  阅读(157)  评论(0编辑  收藏  举报