(gty妹子好多啊。。)
这个题整整调了快一天,真是累死了。。(这么神的题当然是在看某神犇博客的时候看到有这种做法,然后正好就做了233)
其实就是块套树状数组,需要维护成吨的信息,,,,
块与块之间的逆序对数,然后把每个块 i 到最后一个块 j 的逆序对和再搞到树状数组里,然后再来一个树状数组维护处到底 i 个块的时候,有多少个比 j 小的数,其实就是普通的数值插入就好了。(查询的话,块内的就用第一个树状数组求和,第二个就处理块外两部分的逆序对,然后在用第二个树状数组查分一下就可以得到块内有多少个比这个数小,或比这个数大的,答案就有了)
对于修改,一个块自己是可以暴力重构的,对于上面的2个树状数组,因为一个块修改最短引起的是全部块(根号级别)的改动(这个块和其他块的逆序对,这个块之后比..小的数)
所以每次修改的复杂度是log*根号的,每次查询的复杂度也是log*根号的,所以总的复杂度是N*logN*根号N的。
(我的天呢,这种题,,,,,,,,,,简直是无脑。。。。就是码码码码码码码 while(1) cout<<"码";)
1 #include<bits/stdc++.h> 2 #define N 150005 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 #define lowbit(x) x&(-x) 6 using namespace std; 7 inline int ra() 8 { 9 int x=0,f=1; char ch=getchar(); 10 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 11 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 12 return x*f; 13 } 14 int sta[105],top; 15 void writeln(int x) 16 { 17 if (!x) puts("0"); 18 else{ 19 while (x){ sta[++top]=x%10; x/=10;} 20 while (top){ putchar(sta[top]+'0'); top--;} 21 putchar(' ');} 22 } 23 const int M=50005; 24 int c[M],C[305][305],block_small[305][M]; 25 int n,m,Q,B,belong[M],sum[305],L[M],R[M],a[M],ans; 26 void add(int x, int val){for (;x<=n;x+=lowbit(x)) c[x]+=val;} 27 int ask(int x) 28 { 29 int sum=0; 30 for (;x;x-=lowbit(x)) sum+=c[x]; 31 return sum; 32 } 33 34 void block_small_add(int pos, int x, int val){for (;x<=n;x+=lowbit(x)) block_small[pos][x]+=val;} 35 int block_small_ask(int pos, int x) 36 { 37 int sum=0; 38 for (;x;x-=lowbit(x)) sum+=block_small[pos][x]; 39 return sum; 40 } 41 42 void ADD(int pos, int x, int val){for (;x<=m;x+=lowbit(x)) C[pos][x]+=val;} 43 int ASK(int pos, int x) 44 { 45 int sum=0; 46 for (;x;x-=lowbit(x)) sum+=C[pos][x]; 47 return sum; 48 } 49 50 void pre() 51 { 52 for (int i=1; i<=m; i++) L[i]=(i-1)*B+1,R[i]=i*B; R[m]=n; 53 for (int i=1; i<=m; i++) 54 { 55 int tot=0; 56 for (int j=L[i]; j<=R[i]; j++) 57 tot+=ask(n)-ask(a[j]),add(a[j],1); 58 sum[i]=tot; 59 for (int j=i+1; j<=m; j++) 60 { 61 tot=0; 62 for (int k=L[j]; k<=R[j]; k++) 63 tot+=ask(n)-ask(a[k]); 64 ADD(i,j,tot); 65 } 66 for (int j=L[i]; j<=R[i]; j++) 67 add(a[j],-1); 68 } 69 for (int i=1; i<=m; i++) 70 { 71 for (int j=L[i]; j<=R[i]; j++) 72 block_small_add(i,a[j],1); 73 for (int j=1; j<=n; j++) 74 block_small[i+1][j]=block_small[i][j]; 75 } 76 } 77 78 void ask(int x, int y) 79 { 80 ans=0; 81 if (belong[x]==belong[y]) 82 { 83 for (int i=x; i<=y; i++) 84 { 85 ans+=ask(n)-ask(a[i]); 86 add(a[i],1); 87 } 88 for (int i=x; i<=y; i++) add(a[i],-1); 89 } 90 else 91 { 92 for (int i=belong[x]+1; i<belong[y]; i++) 93 ans+=ASK(i,belong[y]-1)+sum[i]; 94 for (int i=x; i<=R[belong[x]]; i++) 95 { 96 ans+=ask(n)-ask(a[i]); 97 ans+=block_small_ask(belong[y]-1,a[i]-1)-block_small_ask(belong[x],a[i]-1); 98 add(a[i],1); 99 } 100 for (int i=L[belong[y]]; i<=y; i++) 101 { 102 ans+=ask(n)-ask(a[i]); 103 ans+=block_small_ask(belong[y]-1,n)-block_small_ask(belong[y]-1,a[i])-block_small_ask(belong[x],n)+block_small_ask(belong[x],a[i]); 104 add(a[i],1); 105 } 106 for (int i=x; i<=R[belong[x]]; i++) add(a[i],-1); 107 for (int i=L[belong[y]]; i<=y; i++) add(a[i],-1); 108 } 109 writeln(ans); 110 } 111 112 void change(int x, int new_val) 113 { 114 if (new_val==a[x]) return; 115 int last=0; 116 for (int i=L[belong[x]]; i<x; i++) 117 { 118 if (a[i]>a[x]) last--; 119 if (a[i]>new_val) last++; 120 } 121 for (int i=x+1; i<=R[belong[x]]; i++) 122 { 123 if (a[x]>a[i]) last--; 124 if (new_val>a[i]) last++; 125 } 126 sum[belong[x]]+=last; 127 for (int i=1; i<belong[x]; i++) 128 { 129 last=0; 130 last-=block_small_ask(i,n)-block_small_ask(i-1,n)-block_small_ask(i,a[x])+block_small_ask(i-1,a[x]); 131 last+=block_small_ask(i,n)-block_small_ask(i-1,n)-block_small_ask(i,new_val)+block_small_ask(i-1,new_val); 132 ADD(i,belong[x],last); 133 } 134 for (int i=belong[x]+1; i<=m; i++) 135 { 136 last=0; 137 last-=block_small_ask(i,a[x]-1)-block_small_ask(i-1,a[x]-1); 138 last+=block_small_ask(i,new_val-1)-block_small_ask(i-1,new_val-1); 139 ADD(belong[x],i,last); 140 } 141 for (int i=belong[x]; i<=m; i++) 142 block_small_add(i,a[x],-1),block_small_add(i,new_val,1); 143 a[x]=new_val; 144 } 145 146 int main() 147 { 148 n=ra(); B=sqrt(n); m=n/B+(n%B!=0); 149 for (int i=1; i<=n; i++) a[i]=ra(),belong[i]=(i-1)/B+1; 150 pre(); Q=ra(); 151 while (Q--) 152 { 153 int opt=ra(),x=ra()^ans,y=ra()^ans; 154 if (opt==0) { ask(x,y);} 155 else change(x,y); 156 } 157 return 0; 158 }