BZOJ3295: [Cqoi2011]动态逆序对

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3295

CDQ分治加凸包,水题一道,看看程序就懂了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define inf 1<<30
 6 #define maxn 100005
 7 #define maxm 50005
 8 using namespace std;
 9 int n,m,t[maxn],a[maxn],b[maxn],f[maxn],ans[maxm];
10 long long sum;
11 struct fuck{int id,x,y;}p[maxm],q[maxm];
12 int read(){
13     int x=0,f=1; char ch;
14     for(ch=getchar();ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
15     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
16     return x*f;
17 }
18 bool cmp(fuck a,fuck b){return a.x<b.x;}
19 void change(int x,int y){for(int i=x;i<=n;i+=i&-i) t[i]+=y;}
20 int query(int x){int y=0; for(int i=x;i;i-=i&-i) y+=t[i]; return y;}
21 void solve(int l,int r){
22     if(l==r) return;
23     int mid=(l+r)>>1;
24     solve(l,mid); solve(mid+1,r);
25     sort(q+l,q+mid+1,cmp); sort(q+mid+1,q+r+1,cmp);
26     int i=l,j=mid+1,last=0;
27     while(j<=r){
28         while(i<=mid&&q[i].x<q[j].x) change(q[i].y,1),last=i++;
29         ans[q[j].id]-=query(q[j].y);
30         j++;
31     }
32     for(int i=l;i<=last;i++) change(q[i].y,-1);
33 }
34 int main(){
35     n=read(); m=read();
36     for(int i=1;i<=n;i++) a[i]=read(),b[a[i]]=i;
37     for(int i=1;i<=m;i++){p[i].y=read(); p[i].x=b[p[i].y]; p[i].id=i;}
38     for(int i=1;i<=n;i++){f[i]+=i-1-query(a[i]); sum+=f[i]; change(a[i],1);}
39     memset(t,0,sizeof(t));
40     for(int i=n;i;i--){f[i]+=query(a[i]); change(a[i],1);}
41     memset(t,0,sizeof(t));
42     for(int i=1;i<=m;i++) ans[i]=f[p[i].x];
43     for(int i=1;i<=m;i++) q[i].id=p[i].id,q[i].x=n+1-p[i].x,q[i].y=p[i].y; solve(1,m);
44     for(int i=1;i<=m;i++) q[i].id=p[i].id,q[i].x=p[i].x,q[i].y=n+1-p[i].y; solve(1,m);
45     for(int i=1;i<=m;i++){printf("%lld\n",sum); sum-=ans[i];}
46     return 0;
47 }
View Code

 

posted @ 2016-05-26 21:05  I'mLS  阅读(130)  评论(0编辑  收藏  举报