bzoj 3744: Gty的妹子序列
阿新 • • 發佈:2018-01-10
接下來 妹子 upd 人間 input 有一個 date tin ()
第一行包括一個整數n(1<=n<=50000),表示數列a中的元素數。
第二行包括n個整數a1...an(ai>0,保證ai在int內)。
接下來一行包括一個整數m(1<=m<=50000),表示詢問的個數。
接下來m行,每行包括2個整數l、r(1<=l<=r<=n),表示詢問al...ar中的逆序
對數(若ai>aj且i<j,則為一個逆序對)。
l,r要分別異或上一次詢問的答案(lastans),最開始時lastans=0。
保證涉及的所有數在int內。
1 4 2 3
1
2 4
每一次查詢復雜度O(√nlogn)
Description
我早已習慣你不在身邊, 人間四月天 寂寞斷了弦。 回望身後藍天, 跟再見說再見…… 某天,蒟蒻Autumn發現了從 Gty的妹子樹(bzoj3720) 上掉落下來了許多妹子,他發現 她們排成了一個序列,每個妹子有一個美麗度。 Bakser神犇與他打算研究一下這個妹子序列,於是Bakser神犇問道:"你知道區間 [l,r]中妹子們美麗度的逆序對數嗎?" 蒟蒻Autumn只會離線亂搞啊……但是Bakser神犇說道:"強制在線。" 請你幫助一下Autumn吧。 給定一個正整數序列a,對於每次詢問,輸出al...ar中的逆序對數,強制在線。Input
Output
對每個詢問,單獨輸出一行,表示al...ar中的逆序對數。
Sample Input
41 4 2 3
1
2 4
Sample Output
2 離線的化應該是O(m√nlogn),在線顯然不會更優 所以把數列分塊 令f[j][i]表示j~第i塊右端所含的逆序對數 pos[i]表示第i為屬於第幾塊 查詢時有2種情況: 1.在同一塊,直接枚舉,用樹狀數組 2.不再同一塊,那麽我們可以把[l,r]分成2塊,分開解決 首先是[l,x=在r前面的塊右端點],直接答案+f[l][pos[x]] 之後考慮[x+1,r]與[l,x]的逆序對數和[x+1,r]自己含有的逆序對數 後者像第1種情況用樹狀數組 前者枚舉i=[l,x],建一棵主席樹求大於a[i]的數量1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 int n,c1[50001],c2[50001],tot; 8 int ch[5000001][2],sum[5000001],a[50001],d[50001],siz,lim,bl[1001],br[1001],cnt; 9 int pos[50001],f[50001][301],root[50001],ans,m; 10 void add1(int x,int d) 11 { 12 while (x<=n) 13 { 14 c1[x]+=d; 15 x+=(x&(-x)); 16 } 17 } 18 void add2(int x,int d) 19 { 20 while (x) 21 { 22 c2[x]+=d; 23 x-=(x&(-x)); 24 } 25 } 26 int query1(int x) 27 { 28 int s=0; 29 while (x) 30 { 31 s+=c1[x]; 32 x-=(x&(-x)); 33 } 34 return s; 35 } 36 int query2(int x) 37 { 38 int s=0; 39 while (x<=n) 40 { 41 s+=c2[x]; 42 x+=(x&(-x)); 43 } 44 return s; 45 } 46 void update(int x,int &y,int l,int r,int k) 47 { 48 y=++tot; 49 ch[y][0]=ch[x][0];ch[y][1]=ch[x][1]; 50 sum[y]=sum[x]+1; 51 if (l==r) return; 52 int mid=(l+r)/2; 53 if (k<=mid) update(ch[x][0],ch[y][0],l,mid,k); 54 else update(ch[x][1],ch[y][1],mid+1,r,k); 55 } 56 int getsum(int x,int y,int l,int r,int L,int R) 57 { 58 if (L>R) return 0; 59 if (l>=L&&r<=R) 60 { 61 return sum[y]-sum[x]; 62 } 63 int mid=(l+r)/2,s=0; 64 if (L<=mid) s+=getsum(ch[x][0],ch[y][0],l,mid,L,R); 65 if (R>mid) s+=getsum(ch[x][1],ch[y][1],mid+1,r,L,R); 66 return s; 67 } 68 int main() 69 {int i,j,l,r,x; 70 cin>>n; 71 for (i=1;i<=n;i++) 72 { 73 scanf("%d",&a[i]); 74 d[i]=a[i]; 75 } 76 sort(d+1,d+n+1); 77 siz=unique(d+1,d+n+1)-d-1; 78 for (i=1;i<=n;i++) 79 a[i]=lower_bound(d+1,d+siz+1,a[i])-d; 80 lim=sqrt(n); 81 for (i=1;i<=n;i+=lim) 82 { 83 bl[++cnt]=i;br[cnt]=min(n,i+lim-1); 84 for (j=bl[cnt];j<=br[cnt];j++) 85 pos[j]=cnt; 86 } 87 for (i=1;i<=cnt;i++) 88 { 89 add1(a[br[i]],1); 90 for (j=br[i]-1;j>=1;j--) 91 { 92 f[j][i]=f[j+1][i]+query1(a[j]-1); 93 add1(a[j],1); 94 } 95 for (j=br[i];j>=1;j--) 96 add1(a[j],-1); 97 } 98 for (i=1;i<=n;i++) 99 { 100 update(root[i-1],root[i],1,n,a[i]); 101 } 102 cin>>m; 103 ans=0; 104 for (i=1;i<=m;i++) 105 { 106 scanf("%d%d",&l,&r); 107 l^=ans;r^=ans; 108 ans=0; 109 if (l>r) 110 {printf("0\n");continue;} 111 if (pos[l]==pos[r]) 112 { 113 for (j=l;j<=r;j++) 114 ans+=query2(a[j]+1),add2(a[j],1); 115 for (j=l;j<=r;j++) 116 add2(a[j],-1); 117 } 118 else 119 { 120 if (br[pos[r]]==r) 121 ans=f[l][pos[r]]; 122 else 123 { 124 ans=f[l][pos[r]-1];x=br[pos[r]-1]; 125 if (x) 126 { 127 for (j=x+1;j<=r;j++) 128 { 129 ans+=getsum(root[l-1],root[x],1,n,a[j]+1,n); 130 } 131 for (j=x+1;j<=r;j++) 132 ans+=query2(a[j]+1),add2(a[j],1); 133 for (j=x+1;j<=r;j++) 134 add2(a[j],-1); 135 } 136 } 137 } 138 printf("%d\n",ans); 139 } 140 }
bzoj 3744: Gty的妹子序列