bzoj 2141: 排队

就是求个动态区间逆序对??是不是和GTY文艺妹子差不多??哦,不是,,,

这个题的话,可以发现的是,每次交换只会对区间内的数产生影响,所以就是求一下区间内比这个L(区间左端点)大的,小的,(减小,加大)比R(区间右端点)大的,小的,(减大,加小),然后把连个数换一下就就行了。。我记得是这样。。而且这个sb题也是调了好久、、、

  1 #include<bits/stdc++.h>
  2 #define N 100005
  3 #define LL long long
  4 #define inf 0x3f3f3f3f
  5 using namespace std;
  6 inline int ra()
  7 {
  8     int x=0,f=1; char ch=getchar();
  9     while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();}
 10     while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();}
 11     return x*f;
 12 }
 13 const int M=5000005;
 14 int a[N],sz,n,ans;
 15 int ls[M],rs[M],s[M],w[M],v[M],rnd[M],root[M];
 16 void update(int k){s[k]=s[ls[k]]+s[rs[k]]+w[k];}
 17 void rturn(int &k){int t=ls[k]; ls[k]=rs[t]; rs[t]=k; s[t]=s[k]; update(k); k=t;}
 18 void lturn(int &k){int t=rs[k]; rs[k]=ls[t]; ls[t]=k; s[t]=s[k]; update(k); k=t;}
 19 void insert(int &k, int num)
 20 {
 21     if (!k) {
 22         k=++sz; w[k]=s[k]=1; ls[k]=rs[k]=0; v[k]=num; rnd[k]=rand(); return;
 23     }
 24     s[k]++;
 25     if (num==v[k]) w[k]++;
 26     else if (num<v[k]) {insert(ls[k],num); if (rnd[ls[k]]<rnd[k]) rturn(k); }
 27     else {insert(rs[k],num); if (rnd[rs[k]]<rnd[k]) lturn(k);}
 28 }
 29 void del(int &k, int num)
 30 {
 31     if (v[k]==num)
 32     {
 33         if (w[k]>1) {s[k]--; w[k]--; return;}
 34         if (ls[k]*rs[k]==0) k=ls[k]+rs[k];
 35         else {if (rnd[ls[k]]<rnd[rs[k]]) rturn(k), del(k,num);
 36                 else lturn(k),del(k,num);
 37         }
 38     }
 39     else if (num<v[k]) del(ls[k],num),s[k]--;
 40         else del(rs[k],num),s[k]--;
 41 }
 42 void build(int k, int l, int r, int x, int num)
 43 {
 44     insert(root[k],num);
 45     if (l==r) return;
 46     int mid=l+r>>1;
 47     if (x<=mid) build(k<<1,l,mid,x,num);
 48     else build(k<<1|1,mid+1,r,x,num);
 49 }
 50 int find1(int k, int num)
 51 {
 52     if (!k) return 0;
 53     if (num==v[k]) return s[ls[k]];
 54     else if (num<v[k]) return find1(ls[k],num);
 55     else return w[k]+s[ls[k]]+find1(rs[k],num);
 56 }
 57 int ask1(int k ,int l, int r, int x, int y, int num)
 58 {
 59     if (l>r || x>y) return 0;
 60     if (l==x && y==r) return find1(root[k],num);
 61     int mid=l+r>>1;
 62     if (y<=mid) return ask1(k<<1,l,mid,x,y,num);
 63     else if (x>mid) return ask1(k<<1|1,mid+1,r,x,y,num);
 64     else return ask1(k<<1,l,mid,x,mid,num)+ask1(k<<1|1,mid+1,r,mid+1,y,num);
 65 }
 66 int find(int k, int num)
 67 {
 68     if (!k) return 0;
 69     if (num==v[k]) return s[ls[k]]+w[k];
 70     else if (num<v[k]) return find(ls[k],num);
 71     else return w[k]+s[ls[k]]+find(rs[k],num);
 72 }
 73 int ask(int k ,int l, int r, int x, int y, int num)
 74 {
 75     if (l>r || x>y) return 0;
 76     if (l==x && y==r) return find(root[k],num);
 77     int mid=l+r>>1;
 78     if (y<=mid) return ask(k<<1,l,mid,x,y,num);
 79     else if (x>mid) return ask(k<<1|1,mid+1,r,x,y,num);
 80     else return ask(k<<1,l,mid,x,mid,num)+ask(k<<1|1,mid+1,r,mid+1,y,num);
 81 }
 82 void change(int k, int l, int r, int pos, int old, int num)
 83 {
 84     del(root[k],old); insert(root[k],num);
 85     if (l==r) return;
 86     int mid=l+r>>1;
 87     if (pos<=mid) change(k<<1,l,mid,pos,old,num);
 88     else change(k<<1|1,mid+1,r,pos,old,num);
 89 }
 90 int main()
 91 {
 92     n=ra();
 93     for (int i=1; i<=n; i++)
 94     {
 95         a[i]=ra();
 96         build(1,1,n,i,a[i]);
 97         ans+=(i-1-ask(1,1,n,1,i-1,a[i]));
 98     //    cout<<(i-1-ask(1,1,n,1,i-1,a[i]))<<endl;
 99     }
100     printf("%d\n",ans);
101     int m=ra();
102     while (m--)
103     {
104         int x=ra(),y=ra();
105         if (x>y) swap(x,y);
106         if (a[x]>a[y]) ans--; if (a[x]<a[y]) ans++;
107         ans+=ask(1,1,n,x+1,y-1,a[y])+ask1(1,1,n,x+1,y-1,a[y])-ask(1,1,n,x+1,y-1,a[x])-ask1(1,1,n,x+1,y-1,a[x]);
108         change(1,1,n,x,a[x],a[y]); change(1,1,n,y,a[y],a[x]);
109         swap(a[x],a[y]);
110     //    for (int i=1; i<=n; i++) printf("%d ",a[i]); cout<<endl;
111         printf("%d\n",ans);
112     }
113     return 0;
114 }
时间: 2024-10-20 00:53:46

bzoj 2141: 排队的相关文章

BZOJ 2141: 排队 CDQ分治+bit

2141: 排队 Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观.设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足ihj的(i,j)数量.幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度.为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序

BZOJ 2141 排队 树套树

题目大意:给出一个数列,支持交换两个数字的操作,问每次操作之后的逆序对数量. 思路:数字比较大,先离散化.然后先求一次总逆序对,每次交换两个数字的时候用树套树维护一下逆序对的总数就可以了.. 好像树套树的常数略大,正解应该是分块.. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 20010 using namesp

BZOJ 2141 排队 分块+树状数组

题目大意:给定一个序列,m次交换两个数,求初始逆序对数及每次交换后的逆序对数 首先离散化,分块,对于每块建立一个树状数组,保存这个块中的所有元素 然后对于每个询问(x,y) (x<y) 两侧的数是没有影响的,区间(x,y)的数a[i]讨论如下: a[i]<a[x] --ans a[i]>a[x] ++ans a[i]<a[y] ++ans a[i]>a[y] --ans 然后对于块中的树状数组处理,块外的暴力 注意此题元素有重复 亲测可信 RANK5吓尿0.0 为何块套树要比

bzoj 3333: 排队计划 题解

[原题] 3333: 排队计划 Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 161  Solved: 71 [Submit][Status] Description Input Output Sample Input 6 2 160 163 164 161 167 160 2 3 Sample Output 6 3 1 HINT Source wyx528命题 [分析]简述一下题目.N个数排成一列,每次指定一个位置P,然后把P~N中所有身高小

[BZOJ 2141][国家集训队 2011]排队 树状数组套平衡树

这道题也就是一个动态逆序对嘛,本质上就是个查询区间排名 刚刚打了一道 [CQOI 2011]动态逆序对  用的线段树套平衡树,代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define pos(i,a,b) for(int i=(a);i<=(b);i++) #define N 101000 #include<cstdlib> #def

bzoj 3333: 排队计划 解决问题的方法

[原标题] 3333: 排队计划 Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 161  Solved: 71 [Submit][Status] Description Input Output Sample Input 6 2 160 163 164 161 167 160 2 3 Sample Output 6 3 1 HINT Source wyx528命题 [分析]简述一下题目.N个数排成一列.每次指定一个位置P,然后把P~N中全部身高

BZOJ 3333: 排队计划 树状数组+线段树

题目大意:给出一个序列,求出这个序列的逆序对数量.定义一种操作,将一个数和他后面比他小的数字拿出来排序, 然后再放回去,之后输出逆序对数. 思路:思路题.手动模拟一下,会发现,逆序对变化的只是排序的那些点 .所以我们只要处理那些点就行了.先求一次逆序对,然后每次在拿出的数后面找到一个最小的数字,把它的权值改成INF,统计答案. CODE: #include <cstdio> #include <cstring> #include <iostream> #include

bzoj 1000+AC

1500 [NOI2005]维修数列   5333 16036 1010 [HNOI2008]玩具装箱toy   5205 12140 2049 [Sdoi2008]Cave 洞穴勘测   4992 10282 1008 [HNOI2008]越狱   4820 11120 1503 [NOI2004]郁闷的出纳员   4629 12915 1208 [HNOI2004]宠物收养所   4216 10462 1026 [SCOI2009]windy数   4169 9168 1003 [ZJOI2

[省选]省选知识点进度

联赛之后记录一下自己的知识点学习情况(按开始时间先后顺序) 可持久化数据结构 [BZOJ 3123]森林 树上主席树 启发式合并 LCA [BZOJ 4826]影魔 区间修改主席树 标记永久化 [BZOJ 2735]世博会 主席树 切比雪夫距离转曼哈顿距离 [BZOJ 3166]Alo 可持久化01Trie [BZOJ 3689]异或之 可持久化01Trie [BZOJ 3261]最大异或和 可持久化01Trie 树套树 [COGS 257]动态排名系统 树状数组套主席树 [BZOJ 2141]