码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ2141: 排队

时间:2016-05-30 18:32:57      阅读:426      评论:0      收藏:0      [点我收藏+]

标签:

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

分块加树状数组。

离散化之后,每一个块建一个树状数组。交换x,y,与x左边的数和y右边的数无关,只需处理>x,<y的数。

话说还可以用树套树来写,不过常数太大,比分块加树状数组慢。

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define inf 1<<30
 7 #define maxn 20005
 8 using namespace std;
 9 int n,m,nn,tot,ans,a[maxn],t[205][maxn];
10 struct fuck{int x,id;}c[maxn];
11 int read(){
12     int x=0,f=1; char ch;
13     for(ch=getchar();ch<0||ch>9;ch=getchar()) if(ch==-) f=-1;
14     for(;ch>=0&&ch<=9;ch=getchar()) x=x*10+ch-0;
15     return x*f;
16 }
17 bool comp(fuck a,fuck b){return a.x<b.x;}
18 int p(int x){return (x-1)/nn+1;}
19 void change(int f,int x,int y){for(int i=x;i<=tot;i+=i&-i) t[f][i]+=y;}
20 int query(int f,int x){int y=0;for(int i=x;i;i-=i&-i) y+=t[f][i];return y;}
21 int main(){
22     n=read(); nn=sqrt(n);
23     for(int i=1;i<=n;i++) c[i].x=read(),c[i].id=i;
24     sort(c+1,c+n+1,comp);
25     for(int i=1;i<=n;i++){
26         if(c[i].x!=c[i-1].x) ++tot;
27         a[c[i].id]=tot;
28     }
29     for(int i=n;i;i--){
30         ans+=query(0,a[i]-1);
31         change(0,a[i],1);
32     }
33     printf("%d\n",ans);
34     for(int i=1;i<=n;i++) change(p(i),a[i],1);
35     m=read();
36     int x,y;
37     while(m--){
38         x=read(); y=read(); if(x>y) swap(x,y);
39         for(int i=p(x)+1;i<p(y);i++){
40             ans-=query(i,a[x]-1); ans+=query(i,tot)-query(i,a[x]);
41             ans-=query(i,tot)-query(i,a[y]); ans+=query(i,a[y]-1);
42         }
43         for(int i=x+1;p(i)==p(x)&&i<y;i++){
44             if(a[i]<a[x]) ans--; if(a[i]>a[x]) ans++;
45             if(a[i]<a[y]) ans++; if(a[i]>a[y]) ans--;
46         }
47         if(p(x)!=p(y))
48         for(int i=y-1;p(i)==p(y);i--){
49             if(a[i]<a[x]) ans--; if(a[i]>a[x]) ans++;
50             if(a[i]<a[y]) ans++; if(a[i]>a[y]) ans--;
51         }
52         if(a[x]<a[y]) ans++; if(a[x]>a[y]) ans--;
53         change(p(x),a[x],-1); change(p(x),a[y],1);
54         change(p(y),a[y],-1); change(p(y),a[x],1);
55         swap(a[x],a[y]);
56         printf("%d\n",ans);
57     }
58     return 0;
59 }
View Code

 

BZOJ2141: 排队

标签:

原文地址:http://www.cnblogs.com/longshengblog/p/5543508.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!