Codeforces 785E. Anton and Permutation

题目链接: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\n",ans);
105     }
106     return 0;
107 }

 


 

posted @ 2017-03-16 21:48  №〓→龙光←  阅读(358)  评论(0编辑  收藏  举报