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. Server 2012 R2 Standard 安装运行PCS7时出现“无法启动此程序,因为计算机中丢失api-ms-win-crt-runtime-l1-1-0.dll”解决方法

    网上看到了这篇文章https://www.jianshu.com/p/21f4bb8b5502,根据思路自己尝试,解决了丢失的问题.提示[计算机中丢失api-ms-win-crt-runtime-l1 ...

  2. 关于vuex的数据不直接给data而要通过computed

    # 为什么vuex的数据不直接给data而要通过computed计算 ## 疑惑 其实一直以来使用vue的状态管理vuex都有一个疑惑,文档中介绍,vue的状态数据`$store.state.xx`的 ...

  3. 二 prometheus 监控 Redis

    Prometheus 监控Redis需要用到redis_exporter客户端, Prometheus -> redis_exporter这个模式, 类似监控Mysql 一个思路. 1 ) 设置 ...

  4. Memcached、Redis、Mongodb比较

    Memcached(内存Cache) Memcached 是一个高性能的分布式内存对象缓存系统.通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像.视频.文件以及数据库 ...

  5. Nginx(六):配置解析之location解析

    nginx成为非常流行的代理服务软件,最根本的原因也许是在于其强悍性能.但还有一些必要的条件,比如功能的完整,配置的易用,能够解决各种各样的实际需求问题,这些是一个好的软件的必备特性. 那么,今天我们 ...

  6. kafka安装流程

    本文是作者原创,版权归作者所有.若要转载,请注明出处. 安装前的环境准备 1.由于Kafka是用Scala语言开发的,运行在JVM上,在安装之前需要先安装JDK(省略) 2.kafka依赖zookee ...

  7. win10打开IIS服务并发布网站

    1.打开控制面板 win+x后点击控制面板 2.点击程序集下边的解除安装程式 3.点击开启或关闭windows功能 4.找到Internet information services并勾选前面的复选框 ...

  8. git 基本命令和操作

    设置全局用户名+密码 $ git config --global user.name 'runoob' $ git config --global user.email test@runoob.com ...

  9. Zju1100 Mondriaan

    题目描述 有一个m行n列的矩阵,用1*2的骨牌(可横放或竖放)完全覆盖,骨牌不能重叠,有多少种不同的覆盖的方法? 你只需要求出覆盖方法总数mod p的值即可. 输入格式 三个整数数n,m,p,m< ...

  10. Java程序入门

    编写Java源程序 在d:\day01 目录下新建文本文件,完整的文件名修改为HelloWorld.java ,其中文件名为HelloWorld ,后缀名必须为.java . 用记事本打开 在文件中键 ...