题目链接:http://codeforces.com/problemset/problem/785/E
其实可以CDQ分治...
我们只要用一个数据结构支持单点修改,区间查询比一个数大(小)的数字有多少个就可以了。
考虑分块,每段区间之内有排序或者二分查询比一个数大的树的个数的操作。
复杂度${O(qn sqrt n log_{2}^{sqrt n})}$
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstdlib> 6 #include<cmath> 7 #include<cstring> 8 using namespace std; 9 #define maxn 1000100 10 #define llg int 11 #define LL long long 12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 13 llg n,m,SIZE,belong[maxn],cnt,ne[maxn],a[maxn],T; 14 LL ans; 15 vector<llg>c[maxn]; 16 17 inline int getint() 18 { 19 int w=0,q=0; char c=getchar(); 20 while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 21 while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w; 22 } 23 24 void init() 25 { 26 SIZE=sqrt(n); 27 for (llg i=1;i<=n;i++) 28 { 29 ne[i]=i+SIZE-1; ne[i]=min(ne[i],n); cnt++; 30 c[cnt].push_back(0); 31 for (llg j=i;j<=ne[i];j++) 32 { 33 ne[j]=ne[i]; 34 belong[j]=cnt; 35 c[cnt].push_back(j); 36 } 37 i=ne[i]; 38 } 39 for (llg i=1;i<=n;i++) a[i]=i; 40 } 41 42 llg erfen(llg x,llg v) 43 { 44 llg l=0,r=c[x].size()-1,mid,wz; 45 while (l<=r) 46 { 47 mid=(l+r)>>1; 48 if (c[x][mid]<=v) {l=mid+1; wz=mid;}else r=mid-1; 49 } 50 return c[x].size()-wz; 51 } 52 53 llg more(llg l,llg r,llg v) 54 { 55 if (r<l) return 0; 56 llg tot=0; 57 llg stk=belong[l],endk=belong[r]; 58 for (llg i=l;i<=r;i++) 59 { 60 if (belong[i]==stk || belong[i]==endk) 61 { 62 if (a[i]>v) tot++; 63 continue; 64 } 65 tot+=erfen(belong[i],v); 66 i=ne[i]; 67 } 68 return tot; 69 } 70 71 void change(llg x,llg v1,llg v2) 72 { 73 llg w=c[x].size(); 74 for (llg i=0;i<w;i++) 75 if (c[x][i]==v1) 76 { 77 c[x][i]=v2; 78 sort(c[x].begin(),c[x].end()); 79 return ; 80 } 81 } 82 83 int main() 84 { 85 // yyj("a"); 86 cin>>n>>T; 87 init(); 88 while (T--) 89 { 90 llg l,r; 91 l=getint(),r=getint(); 92 if (l>r) swap(l,r); 93 if (l!=r) 94 { 95 llg morel=more(l+1,r-1,a[l]); 96 llg lessl=r-1-l-morel; 97 llg morer=more(l+1,r-1,a[r]); 98 llg lessr=r-1-l-morer; 99 ans+=morel-lessl+lessr-morer; 100 if (a[l]>a[r]) ans--;else ans++; 101 change(belong[l],a[l],a[r]); change(belong[r],a[r],a[l]); 102 swap(a[l],a[r]); 103 } 104 printf("%I64d ",ans); 105 } 106 return 0; 107 }