【bzoj 3333】排队计划(线段树)
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】排队计划(线段树)的更多相关文章
- bzoj 3333: 排队计划 解决问题的方法
[原标题] 3333: 排队计划 Time Limit: 20 Sec Memory Limit: 128 MB Submit: 161 Solved: 71 [Submit][Status] D ...
- BZOJ 3333 排队计划 树状数组+线段树
题目大意:给定一个序列.每次选择一个位置,把这个位置之后全部小于等于这个数的数抽出来,排序,再插回去,求每次操作后的逆序对数 首先我们每一次操作 对于这个位置前面的数 因为排序的数与前面的数位置关系不 ...
- Bzoj 2752 高速公路 (期望,线段树)
Bzoj 2752 高速公路 (期望,线段树) 题目链接 这道题显然求边,因为题目是一条链,所以直接采用把边编上号.看成序列即可 \(1\)与\(2\)号点的边连得是. 编号为\(1\)的点.查询的时 ...
- BZOJ.3938.Robot(李超线段树)
BZOJ UOJ 以时间\(t\)为横坐标,位置\(p\)为纵坐标建坐标系,那每个机器人就是一条\(0\sim INF\)的折线. 用李超线段树维护最大最小值.对于折线分成若干条线段依次插入即可. 最 ...
- BZOJ.1558.[JSOI2009]等差数列(线段树 差分)
BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...
- bzoj 3772 :精神污染 线段树+打标记 or 主席树
3772: 精神污染 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 315 Solved: 87[Submit][Status][Discuss] D ...
- BZOJ 3813--奇数国(线段树&欧拉函数&乘法逆元&状态压缩)
3813: 奇数国 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 755 Solved: 432[Submit][Status][Discuss] ...
- HDU 3333 Turing Tree 线段树+离线处理
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Othe ...
- [NOIP2015]运输计划 线段树or差分二分
目录 [NOIP2015]运输计划 链接 思路1 暴力数据结构 思路2 二分树上差分 总的 代码1 代码2 [NOIP2015]运输计划 链接 luogu 好久没写博客了,水一篇波. 思路1 暴力数据 ...
- BZOJ 3779: 重组病毒(线段树+lct+树剖)
题面 escription 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病 ...
随机推荐
- 【渲染教程】使用3ds Max和ZBrush制作卡通风格的武器模型(上)
克里斯蒂娜·马丁(CristinaMartín)介绍了她的项目灵剑(Spirit Sword)的制作过程,并详细的展示了使用3ds Max和ZBrush制作模型,纹理绘画和最终展示的过程. 介绍 克里 ...
- 【MySQL】汇总数据 - avg()、count()、max()、min()、sum()函数的使用
第12章 汇总数据 文章目录 第12章 汇总数据 1.聚集函数 1.1.AVG()函数 avg() 1.2.COUNT()函数 count() 1.3. MAX()函数 max() 1.4.MIN() ...
- --safe-user-create
此参数如果启用,用户将不能用grant语句创建新用户,除非用户有mysql数据库中user表的insert权限, ./mysqld_safe --safe-user-create & 用-- ...
- 【Python】PDF转WORD
注意,下文中的PDF文档是纯文字格式,而且非扫描版的PDF文件. 如果是扫描版或者带有图片的.可能转起来会出现排版异常并且图片无法保存到.doc文件中. 正文开始: 需要安装依赖包 pdfminer3 ...
- leetcode 1240. 铺瓷砖(回溯,DFS)
题目链接 https://leetcode-cn.com/problems/tiling-a-rectangle-with-the-fewest-squares/ 题意: 用尽可能少的正方形瓷砖来铺地 ...
- SpringBoot快速掌握(1):核心技术
SpringBoot快速掌握(1):核心技术 SpringBoot快速掌握(1):核心技术 SpringBoot快速掌握(1):核心技术 SpringBoot快速掌握(1):核心技术 SpringBo ...
- 关于springboot项目通过jar包启动之后无法读取项目根路径静态资源
在一次项目开发过程中,项目根路径下存放了一张图片,生成二维码的时候调用了该图片作为二维码的logo,在windows环境下二维码可以正常生成,但是部署到生产测试环境之后二维码生成报错,FileNotF ...
- 一个简单的IM聊天程序Pie IM(以后会更新)
这个程序用多线程,实现设备之间的聊天,支持win10通知,欢迎下载 依赖的第三方库 win10toast 代码 将以下代码写入任意.py文件 1 print('Welcome to use Pie I ...
- Vue基础之插值表达式的另一种用法!附加变量的监听!
Vue基础之插值表达式的另一种用法!附加变量的监听! 讲这个之前我们先回顾一下原来的用法! <body> <!-- Vue.js的应用可以分为两个重要的组成部分 一个是视图! 另一个 ...
- 编译Nacos,解决No Server available 以及 failed to req API__nacos_v1_ns_instance after all servers
问题描述:如图,显示没有服务可用 仔细看控制台,看到上面Error部分,相关参数没有读取到配置信息,那么配置信息这块似乎是有问题,赶紧看看IDE对配置信息的扫描情况: 可以看到有信息了,但是报错:No ...