【分块】【树状数组】bzoj3787 Gty的文艺妹子序列
题解懒得自己写了,Orz一发wangxz神犇的:
http://bakser.gitcafe.com/2014/12/04/bzoj3787-Gty%E7%9A%84%E6%96%87%E8%89%BA%E5%A6%B9%E5%AD%90%E5%BA%8F%E5%88%97-%E5%AE%98%E6%96%B9%E9%A2%98%E8%A7%A3/
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 using namespace std; 5 int n,m,op,sum; 6 struct BIT 7 { 8 int d[50001]; 9 void add_node(int p,const int &v) 10 {for(;p<=n;p+=(p&(-p))) d[p]+=v;} 11 int query(int p) 12 {int res=0; for(;p;p-=(p&(-p))) res+=d[p]; return res;} 13 }T[230],S; 14 struct BIT2 15 { 16 int d[230]; 17 void add_node(int p,const int &v) 18 {for(;p<=sum;p+=(p&(-p))) d[p]+=v;} 19 void add_range(const int &L,const int &R,const int &v) 20 {add_node(L,v); if(R!=sum) add_node(R+1,-v);} 21 int query(int p) 22 {int res=0; for(;p;p-=(p&(-p))) res+=d[p]; return res;} 23 }Xs[230],Ys[230]; 24 int sz,l[230],x,y,r[230],a[50001],num[50001],f[230][230],ans; 25 void makeblock() 26 { 27 sz=(int)(sqrt(n)/sqrt(log2(n))); if(!sz) sz=1; 28 for(sum=1;sum*sz<n;++sum) 29 { 30 l[sum]=r[sum-1]+1; r[sum]=sum*sz; 31 for(int i=l[sum];i<=r[sum];++i) num[i]=sum; 32 } 33 l[sum]=r[sum-1]+1; r[sum]=n; 34 for(int i=l[sum];i<=r[sum];++i) num[i]=sum; 35 } 36 void init_BITs() 37 { 38 for(int i=1;i<=sum;++i) 39 { 40 T[i]=T[i-1]; 41 for(int j=l[i];j<=r[i];++j) T[i].add_node(a[j],1); 42 } 43 } 44 void init_anss() 45 { 46 for(int i=1;i<=sum;++i) 47 { 48 memset(S.d,0,sizeof(S.d)); int pos=0,res=0; 49 for(int j=i;j<=sum;++j) 50 { 51 for(int k=l[j];k<=r[j];++k) 52 { 53 ++pos; 54 S.add_node(a[k],1); 55 res+=(pos-S.query(a[k])); 56 } 57 f[i][j]=res; 58 } 59 } memset(S.d,0,sizeof(S.d)); 60 } 61 int getMore(const int &L,const int &R,const int &v) 62 {return sz*(R-L+1)-(T[R].query(v)-T[L-1].query(v));} 63 int getLess(const int &L,const int &R,const int &v) 64 {return T[R].query(v-1)-T[L-1].query(v-1);} 65 void Query() 66 { 67 if(num[x]+1>=num[y]) 68 { 69 int pos=0; ans=0; 70 for(int i=x;i<=y;i++) 71 { 72 pos++; 73 S.add_node(a[i],1); 74 ans+=(pos-S.query(a[i])); 75 } 76 for(int i=x;i<=y;i++) S.add_node(a[i],-1); 77 printf("%d\n",ans); 78 } 79 else 80 { 81 int pos=r[num[x]]-x+1; 82 ans=f[num[x]+1][num[y]-1]+Xs[num[x]+1].query(num[y]-1)+Ys[num[y]-1].query(num[x]+1); 83 for(int i=r[num[x]];i>=x;--i) 84 { 85 ans+=(getLess(num[x]+1,num[y]-1,a[i])+S.query(a[i]-1)); 86 S.add_node(a[i],1); 87 } 88 for(int i=l[num[y]];i<=y;++i) 89 { 90 pos++; 91 S.add_node(a[i],1); 92 ans+=(pos-S.query(a[i])+getMore(num[x]+1,num[y]-1,a[i])); 93 } 94 for(int i=x;i<=r[num[x]];++i) S.add_node(a[i],-1); 95 for(int i=l[num[y]];i<=y;++i) S.add_node(a[i],-1); 96 printf("%d\n",ans); 97 } 98 } 99 void Update() 100 { 101 int Pre=0,Nex=0; int &xB=num[x]; 102 for(int i=l[xB];i<x;++i) if(a[i]>a[x]) --Pre; 103 for(int i=l[xB];i<x;++i) if(a[i]>y) ++Pre; 104 for(int i=x+1;i<=r[xB];++i) if(a[i]<a[x]) --Nex; 105 for(int i=x+1;i<=r[xB];++i) if(a[i]<y) ++Nex; 106 int t1=T[xB-1].query(a[x]); 107 int t2=T[xB-1].query(y); 108 for(int i=1;i<=xB;++i) 109 { 110 Xs[i].add_range(xB,sum,-((xB-i)*sz-(t1-T[i-1].query(a[x])))); 111 Xs[i].add_range(xB,sum,(xB-i)*sz-(t2-T[i-1].query(y))+Pre); 112 } 113 t1=T[xB].query(a[x]-1); 114 t2=T[xB].query(y-1); 115 for(int j=xB;j<=sum;++j) 116 { 117 Ys[j].add_range(1,xB,t1-T[j].query(a[x]-1)); 118 Ys[j].add_range(1,xB,T[j].query(y-1)-t2+Nex); 119 } 120 for(int i=xB;i<=sum;++i) 121 { 122 T[i].add_node(a[x],-1); 123 T[i].add_node(y,1); 124 } 125 a[x]=y; 126 } 127 int main() 128 { 129 scanf("%d",&n); 130 for(int i=1;i<=n;++i) scanf("%d",&a[i]); 131 makeblock(); init_BITs(); init_anss(); 132 scanf("%d",&m); 133 for(;m;--m) 134 { 135 scanf("%d%d%d",&op,&x,&y); x^=ans; y^=ans; 136 if(!op) Query(); 137 else Update(); 138 } 139 return 0; 140 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。