n个数,求一次逆序对。接着有m次修改操作,把每次输入的位置p的数之后<=它的数取出来,从小到大排序后再放回空位里,求逆序对。(N,M<=500,000 , Ai<=10^9)
思路:
1.往后修改就存后缀,而不是一般的前缀。存数 i 之后<=它的数的个数为s[i],用于后续求逆序对。
2.修改时选出的数排序后,它们的 s[] 都清零了,也可以“删掉”它们了——更改其值为INF。
实现:
1.用树状数组(或线段树)求出初始的逆序对数 sum。
2.每次操作用线段树在p到n的区间内找到所有<=数p 的数,通过一次次找最小的数,sum减去它的 s[] 值,更改其值为INF来进行“删除”。
3.线段树中权值存最小的数的编号,这样方便直接找到它。一个个删点也不用担心超时,因为“删”了之后就不会找到它了,为O(n),找最小的数为O(log n),整个程序为O(n log n)的时间复杂度。

  1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 #include<algorithm>
6 using namespace std;
7 typedef long long LL;
8
9 const LL N=500010,INF=(LL)1e9+100;
10 LL n,m;
11 LL b[N],s[N],c[N];
12 struct node{LL l,r,lc,rc,id;}a[N*2];
13 LL len=0;
14 struct hp{LL x,t;}e[N];
15
16 LL mmin(LL x,LL y)
17 { return x<y?x:y; }
18 LL cp(LL x,LL y)
19 { return b[x]<b[y]?x:y; }
20
21 void bt(LL l,LL r)
22 {
23 LL x=++len;
24 a[x].l=l,a[x].r=r;
25 a[x].lc=a[x].rc=-1;
26 if (l==r) a[x].id=l;
27 else a[x].id=0;
28 if (l<r)
29 {
30 LL mid=(l+r)/2;
31 a[x].lc=len+1,bt(l,mid);
32 a[x].rc=len+1,bt(mid+1,r);
33
34 LL lc=a[x].lc,rc=a[x].rc;
35 a[x].id=cp(a[lc].id,a[rc].id);
36 }
37 }
38 void change(LL x,LL p,LL id)
39 {
40 if (a[x].l==a[x].r) {a[x].id=n+1;return;}
41 LL lc=a[x].lc,rc=a[x].rc,mid=(a[x].l+a[x].r)/2;
42 if (p<=mid) change(lc,p,id);
43 else change(rc,p,id);
44 a[x].id=cp(a[lc].id,a[rc].id);
45 }
46 LL getmin(LL x,LL l,LL r)
47 {
48 if (a[x].l==l&&a[x].r==r) return a[x].id;
49 LL lc=a[x].lc,rc=a[x].rc,mid=(a[x].l+a[x].r)/2;
50 if (r<=mid) return getmin(lc,l,r);
51 if (l>mid) return getmin(rc,l,r);
52 return cp(getmin(lc,l,mid),getmin(rc,mid+1,r));
53 }
54
55 bool cmp(hp u,hp v)
56 { return u.x<v.x; }
57
58 LL lowbit(LL x) {return x&-x;}
59 LL S(LL x)
60 {
61 LL h=0;
62 for (LL i=x;i>=1;i-=lowbit(i))
63 h+=c[i];
64 return h;
65 }
66 void C(LL x)
67 { for (LL i=x;i<=n;i+=lowbit(i)) c[i]++; }
68
69 int main()
70 {
71 scanf("%lld%lld",&n,&m);
72 for (LL i=1;i<=n;i++)
73 scanf("%lld",&e[i].x),e[i].t=i;
74 sort(e+1,e+1+n,cmp);
75 LL x=0;
76 e[0].x=INF;
77 for (LL i=1;i<=n;i++)
78 {
79 if (e[i].x!=e[i-1].x) x++;
80 b[e[i].t]=x;
81 }
82 b[n+1]=INF;
83 LL sum=0;
84 memset(c,0,sizeof(c));
85 for (LL i=n;i>=1;i--)
86 {
87 s[i]=S(b[i]-1);
88 sum+=s[i];
89 C(b[i]);
90 }
91 printf("%lld\n",sum);
92 bt(1,n);
93 while (m--)
94 {
95 LL p;
96 scanf("%lld",&p);
97 LL t=b[p],k=getmin(1,p,n),h=0;
98 while (b[k]<=t)
99 {
100 h+=s[k];//
101 change(1,k,n+1);
102 k=getmin(1,p,n);
103 }
104 sum-=h;
105 printf("%lld\n",sum);
106 }
107 return 0;
108 }

P.S.OJ的评测系统为Linux,用 %lld 输出 longlong 类型,在本机的Windows上用 %I64d。

【bzoj 3333】排队计划(线段树)的更多相关文章

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

    [原标题] 3333: 排队计划 Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 161  Solved: 71 [Submit][Status] D ...

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

    题目大意:给定一个序列.每次选择一个位置,把这个位置之后全部小于等于这个数的数抽出来,排序,再插回去,求每次操作后的逆序对数 首先我们每一次操作 对于这个位置前面的数 因为排序的数与前面的数位置关系不 ...

  3. Bzoj 2752 高速公路 (期望,线段树)

    Bzoj 2752 高速公路 (期望,线段树) 题目链接 这道题显然求边,因为题目是一条链,所以直接采用把边编上号.看成序列即可 \(1\)与\(2\)号点的边连得是. 编号为\(1\)的点.查询的时 ...

  4. BZOJ.3938.Robot(李超线段树)

    BZOJ UOJ 以时间\(t\)为横坐标,位置\(p\)为纵坐标建坐标系,那每个机器人就是一条\(0\sim INF\)的折线. 用李超线段树维护最大最小值.对于折线分成若干条线段依次插入即可. 最 ...

  5. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

  6. bzoj 3772 :精神污染 线段树+打标记 or 主席树

    3772: 精神污染 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 315  Solved: 87[Submit][Status][Discuss] D ...

  7. BZOJ 3813--奇数国(线段树&欧拉函数&乘法逆元&状态压缩)

    3813: 奇数国 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 755  Solved: 432[Submit][Status][Discuss] ...

  8. HDU 3333 Turing Tree 线段树+离线处理

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Othe ...

  9. [NOIP2015]运输计划 线段树or差分二分

    目录 [NOIP2015]运输计划 链接 思路1 暴力数据结构 思路2 二分树上差分 总的 代码1 代码2 [NOIP2015]运输计划 链接 luogu 好久没写博客了,水一篇波. 思路1 暴力数据 ...

  10. BZOJ 3779: 重组病毒(线段树+lct+树剖)

    题面 escription 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病 ...

随机推荐

  1. 在IDEA中通过Module管理多个项目

    你身边有没有这种顽固的Eclipse忠实用户:IDEA不能一个窗口管理多个项目!太不方便了! 对于一个窗口同时管理多个项目的需求,在我们日常开发时候是经常需要的.尤其当我们在分布式环境下,在一个窗口中 ...

  2. 【Linux】saltstack的使用详解 超详细

    一.salt常用命令 salt 该命令执行salt的执行模块,通常在master端运行,也是我们最常用到的命令 salt [options] '<target>' <function ...

  3. linux命名小技巧(持续更新)

    一   向某个文件批量加入内容 1.1 向/etc/wxm文件添加一大段内容可以使用这个命令 [root@registry easyrsa3]# cat <<EOF >varsset ...

  4. oracle rac与单实例DG切换

    1.主库查看状态(RAC库) SQL> select database_role,switchover_status from v$database; DATABASE_ROLE SWITCHO ...

  5. CodeMonkey少儿编程第3章 times循环

    目标 了解程序由哪三种基本的结构组成 了解循环的概念 掌握times的结构与用法 三种基本结构 计算机程序由三种最基本的结构组成,它们分别是: 顺序结构 循环结构 选择结构 千万不要被这些陌生的术语给 ...

  6. Flask的“中间件”

    特殊装饰器 from flask import Flask,render_template,request app = Flask(__name__) @app.before_request def ...

  7. linux中的虚拟环境工具

    1.虚拟环境工具的学习 python的虚拟环境,其实就是在机器上,方便的创建出多个解释器,每个解释器运行一个项目,互相之间不受影响 2.virtualenv工具,可以方便的创建,使用,删除也很方便 3 ...

  8. Go - httpclient 常用操作

    httpclient 模块介绍 httpclient 是基于 net/http  封装的 Go HTTP 客户端请求包,支持常用的请求方式.常用设置,比如: 支持设置 Mock 信息 支持设置失败时告 ...

  9. Python小度

    这只是一个对话器!还不能听歌(反正我也没在UNIT平台配置听歌的功能)! 反正最近也不知怎么的,就想做一个AI对话器语音识别和语音输出都不要,input()和print()就行本来准备用小爱的,但要实 ...

  10. ETCD数据迁移

    ETCD数据迁移 本文阅读对象为想要将Rainbond平台rbd-etcd切换至外部etcd的相关人员. 在k8s master节点创建secret 本文中将要切换的ETCD为根据Rainbond官方 ...