Block entry bzoj2141 queue

Keywords: less

To infinity and beyond. -<Wall-E>  

First of all, we can use the discretization + tree array to calculate the time complexity (n log n) of the number of reverse order pairs

For questions about the reverse order pair, we can first think of the characteristics of the reverse order pair:

Then for each inquiry (x,y) (x < y), the number on both sides has no effect. The number a[i] of interval (x,y) is discussed as follows:

a[i]<a[x] --ans

a[i]>a[x] ++ans

a[i]<a[y] ++ans

a[i]>a[y] --ans

At this time, I want to use block processing

For n-number blocks, what we need to do in each block is to determine how many blocks are more than a [x] or (a[y]) (this step can be treated equivalently (a tip))

Consider tree array

But at this time, it will be faster if we use block processing

For data weight block

ha[k][i] represents the number less than base*i in the k-th block number. At the same time, use pre[k][i] table to record the number of < = I & & > base * (I / base) in the k-th block number, so as to record the smaller intervals on both sides of the block

Code:

#Include < bits / STDC + +. H > / / block nesting 
using namespace std;
const int maxn=500000;
long long n,m,cnt,u,v,a[maxn],b[maxn],sum[maxn],ha[201][201],pre[201][20001],k1,k2,k3,block;
long long query(int x)
{long long ans=0; for (int i=x;i;i-=(i&-i)) ans+=sum[i]; return ans;}
void  add(int x) { for (int i=x;i<=maxn;i+=(i&-i)) sum[i]++;}
int getblock(int x) { return (x-1)/block+1;}
void change(int k,int zhi,int an)  //Process the current block 
{  int kzhi=getblock(zhi);
  for (int i=kzhi+1;i<=getblock(n);i++) ha[k][i]+=an;
  for (int i=zhi;i<=(kzhi)*block;i++) pre[k][i]+=an;
}
int ask(int l,int r,int zhi)
{
  if (l>r) return 0;
  k1=getblock(l);
  k2=getblock(r);
  long long sum=0;
  if (k1==k2) { for (int i=l;i<=r;i++){if (zhi>b[i]) sum++; if (zhi>=b[i]) sum++; }}
  else
  { 
    for (int i=l;i<=k1*block;i++)
    {{if (zhi>b[i]) sum++; if (zhi>=b[i]) sum++; }}
    for (int i=(k2-1)*block+1;i<=r;i++)
    {{if (zhi>b[i]) sum++; if (zhi>=b[i]) sum++; }}
    k3=getblock(zhi);
  	for (int  i=k1+1;i<k2;i++)
  	{ sum+=ha[i][k3]+pre[i][zhi]; }
  	 zhi--;
  	k3=getblock(zhi);
  	for (int  i=k1+1;i<k2;i++)
  	{ sum+=ha[i][k3]+pre[i][zhi]; }
  	
  }
  return (sum-(r-l+1));
}
int main()
{  
  cin>>n;
  for (int i=1;i<=n;i++) {cin>>b[i]; a[i]=b[i]; }
  sort(a+1,a+1+n);
  for (int i=1;i<=n;i++)  {b[i]=lower_bound(a+1,a+1+n,b[i])-a; //Discretization operation 
                           b[i]=n+1-b[i];}
  for (int i=1;i<=n;i++) { cnt+=query(b[i]-1); add(b[i]);}
  block=200;
  cout<<cnt<<endl;
  for (int i=1;i<=n;i++)
  { change(getblock(i),b[i],1);}
  cin>>m;
  for (int i=1;i<=m;i++)
  {
  	cin>>u>>v;
  	if (b[u]==b[v]) { cout<<cnt<<endl; continue;}
  	if (u>v) swap(u,v);
  	cnt+=ask(u+1,v-1,b[u]);//Find the number smaller than b[u] in u+1--v-1 interval and subtract the number larger than b[u] 
  	cnt-=ask(u+1,v-1,b[v]);
  	if (b[u]>b[v]) cnt++; else cnt--;
  	change(getblock(u),b[u],-1);	change(getblock(v),b[v],-1);
  	change(getblock(v),b[u],1);	    change(getblock(u),b[v],1);
  	swap(b[u],b[v]); 
	cout<<cnt<<endl;
  }
} 

 

Posted by priya_cks on Sat, 04 Jan 2020 09:29:16 -0800