The subject of the problem: with modified, forced online in reverse order
Rewrite one of the previous 3744TLE methods to change some of the preprocessing to a tree-like array have to say the tree array constant or small
G[I][J] (I<=J) represents the reverse order between the elements in block I and the elements in block i~j the first dimension of violence the second-dimensional tree array maintains the prefix and
EQUALS[I][J] Indicates the number of J within the front I block this direct violence can be
SMALLER[I][J] represents the number of numbers within the first I block less than or equal to J a second-dimensional tree array of violence
When you modify the query, we first divide the interval into three blocks.
Make a for the left fragmented part B is the middle block Part C is the right fragmented part
BB Direct call g array time complexity O (√NLOGN)
AB uses equals and smaller arrays to find the amount of time complexity O (√NLOGN) for the number of elements in each element B in a that is smaller than that element.
BC uses the B-part size and the smaller array to find the amount of time complexity O (√NLOGN) for a number larger than that element in each element B in C
Then put part A and part C together on the bit (I lazy wrote merge_sort) AA, AC, CC are all out
Total time complexity not exceeding O (N√NLOGN)
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include < algorithm> #define M 50500#define sqrt_m 250using namespace Std;int n,m,block,ans;int a[m],b[m];int F[sqrt_m][sqrt_m] ;//f[i][i] means that the inverse logarithm of the inner Part I//f[i][j] (I<J) represents the reverse order between the elements in block I and the elements in block J, int g[sqrt_m][sqrt_m];//g[i][j] (i<=j) Represents the reverse order between the elements in block I and the elements in block I~J//first-dimensional violence second-dimensional tree array prefixes and//upward modification query int equals[sqrt_m][m];int SMALLER[SQRT_M][M];/*EQUALS[I][J] Indicates the number of J within the front I block direct violence smaller[i][j] represents the number of numbers less than or equal to J in the front I block upward modification downward query the first dimension of violence second-dimensional tree array */int l[sqrt_m],r[sqrt_m],belong[m];int Merge_ Sort (int l,int r,int b[]=::b) {static int c[m]; int i,mid=l+r>>1,re=0; if (l==r) return 0; Re=merge_sort (l,mid,b) +merge_sort (mid+1,r,b); int l1=l,l2=mid+1; for (i=l;i<=r;i++) {if (B[l1]<=b[l2] && l1<=mid | | l2>r) C[I]=B[L1++],RE+=L2-MID -1; else c[i]=b[l2++]; } memcpy (B+l, c+l, sizeof (b[0]) * (r-l+1)); return re;} void Update (int c[],int x,int Y,int limit) {for (; x<=limit;x+=x&-x) c[x]+=y;} int Get_ans (int c[],int x) {int re=0; for (; x;x-=x&-x) re+=c[x]; return re;} void Modify (int x,int y) {int i,j,_block=belong[x],temp; for (i=1;i<_block;i++) {temp=upper_bound (b+l[i],b+r[i]+1,y)-upper_bound (b+l[i],b+r[i]+1,a[x]); Update (G[i],_block,-temp, (n-1)/block+1); } for (i=_block+1; (i-1) *block+1<=n;i++) {temp=lower_bound (b+l[i],b+r[i]+1,y)-lower_bound (b+l[i],b+r[i]+1,a [x]); Update (G[_block],i,temp, (n-1)/block+1); } memcpy (B+l[_block],a+l[_block],sizeof (b[0]) * (r[_block]-l[_block]+1)); B[x]=y; Temp=merge_sort (L[_block],r[_block]); Refactoring b array Update (G[_block],_block,temp-f[_block][_block], (n-1)/block+1); F[_block][_block]=temp; Modify F[i][i] and g[i][~] for (i=_block; (i-1) *block+1<=n;i++) {equals[i][a[x]]--, equals[i][y]++; Update (Smaller[i],a[x],-1,n); Update (Smaller[i],y,1,n); }//Modify the number of euqal and smallerGroup A[x]=y; Modify the A array}int Query (int x,int y) {static int c[m]; int i,top=0,re=0; if (belong[y]-belong[x]<=1) {memcpy (c+x,a+x,sizeof (a[0]) * (y-x+1)); Return Merge_sort (X,Y,C); } for (i=belong[x]+1;i<belong[y];i++) Re+=get_ans (g[i],belong[y]-1); BB for (i=x;i<=r[belong[x]];i++) {Re+=get_ans (Smaller[belong[y]-1],a[i])-get_ans (Smaller[belong[x]],a[i] )-(Equals[belong[y]-1][a[i]]-equals[belong[x]][a[i]); C[++top]=a[i]; }//ab for (i=l[belong[y]];i<=y;i++) {re+=r[belong[y]-1]-r[belong[x]]-(Get_ans (Smaller[bel Ong[y]-1],a[i])-get_ans (Smaller[belong[x]],a[i]); C[++top]=a[i]; }//BC return Re+merge_sort (1,TOP,C); Aa+ac+cc}int Main () {int i,j,k; int p,x,y; cin>>n; for (i=1;i<=n;i++) scanf ("%d", &a[i]); Block=static_cast<int> (sqrt (n) +1e-7); for (i=1;i<=n;i++) {belong[i]= (i-1)/block+1; b[i]=A[i]; } for (I=1; (i-1) *block+1<=n;i++) {l[i]= (i-1) *block+1,r[i]=min (i*block,n); F[i][i]=merge_sort (L[i],r[i]); }//preprocessing block and F[i][i] for (I=1, (i-1) *block+1<=n;i++) for (j=i+1; (j-1) *block+1<=n;j++) {int P=L[J]; for (k=l[i];k<=r[i];k++) {for (;p <=r[j]&&b[p]<b[k];p + +); F[I][J]+=P-L[J]; }} for (I=1; (i-1) *block+1<=n;i++) for (j=i; (j-1) *block+1<=n;j++) Update (G[i],j,f[i][j], (n -1)/block+1); preprocessing f arrays and G arrays for (i=1;i<=n;i++) for (j=belong[i];j<= (n-1)/block+1;j++) {equals[j][a[i]]+ +; Update (Smaller[j],a[i],1,n); }//preprocessing equals array and smaller array cin>>m; for (i=1;i<=m;i++) {scanf ("%d%d%d", &p,&x,&y); X^=ans;y^=ans; if (p==1) Modify (x, y); else printf ("%d\n", Ans=query (x, y)); }}
Bzoj 3787 Gty's literary sister series sub-block + tree-like array