luogu3157 动态逆序对
题目大意
给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。
思路

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int MAX_INDEX = 100010, MAX_MAXVAL = MAX_INDEX, MAX_DEL_CNT = 50010, MAX_NODE = 9e6;
int Queries[MAX_DEL_CNT];
long long Ans[MAX_DEL_CNT];
int TotIndex, TotDelCnt, MaxVal; struct Data
{
int Index, Val, AddTime; bool operator < (const Data& a) const
{
return AddTime < a.AddTime;
}
}_datas[MAX_INDEX]; struct Node
{
int lSonId, rSonId;
int Cnt; Node() :lSonId(0), rSonId(0), Cnt(0) {}
}_nodes[MAX_NODE];
int _vCount; struct RangeTree
{
private:
int RootId; Node *NewNode()
{
return _nodes + ++_vCount;
} void Update(int &curId, int l, int r, int p, int delta)
{
Node *cur = _nodes + curId;
if (!curId)
{
cur = NewNode();
curId = cur - _nodes;
}
cur->Cnt += delta;
if (l == r)
return;
int mid = (l + r) / 2;
if (p <= mid)
Update(cur->lSonId, l, mid, p, delta);
if (p > mid)
Update(cur->rSonId, mid + 1, r, p, delta);
} long long QueryPrefix(int k)
{
Node *cur = RootId ? _nodes + RootId : NULL;
int l = 1, r = MaxVal;
long long ans = 0;
while (l < r && cur)
{
int mid = (l + r) / 2;
if (k >= mid)
{
ans += cur->lSonId ?_nodes[cur->lSonId].Cnt :0;
cur = cur->rSonId ? _nodes + cur->rSonId : NULL;
l = mid + 1;
}
else
{
cur = cur->lSonId ? _nodes + cur->lSonId:NULL;
r = mid;
}
}
return ans;
} long long QuerySuffix(int k)
{
Node *cur = RootId ? _nodes + RootId : NULL;
if (!cur)
return 0;
return cur->Cnt - QueryPrefix(k-1);
} public:
RangeTree() :RootId(0) {} void Update(int p, int delta)
{
if (p < 1 || p > MaxVal)
return;
Update(RootId, 1, MaxVal, p, delta);
} long long Query(int l, int r)
{
if (l > r)
return 0;
long long ans1 = 0;
if (l == 1)
{
ans1 = QueryPrefix(r);
return ans1;
}
else if (r == MaxVal)
{
ans1= QuerySuffix(l);
return ans1; }
else
return 0;
}
}; struct BinaryTree
{
private:
RangeTree C[MAX_MAXVAL];
int N; int Lowbit(int x)
{
return x & -x;
} public:
BinaryTree(int n) :N(n) {} void Update(int p, int delta)
{
if (p < 0)
return;
while (p <= N)
{
C[p].Update(delta, 1);
p += Lowbit(p);
}
} long long Query(int p, long long(*getVal)(RangeTree&, int), int cKey)
{
long long ans = 0;
while (p > 0)
{
ans += getVal(C[p], cKey);
p -= Lowbit(p);
}
return ans;
}
}*a; long long Range_GetIdGreaterCnt(RangeTree& tree, int k)
{
return tree.Query(k + 1, MaxVal);
} long long Range_GetIdLesserCnt(RangeTree& tree, int k)
{
return tree.Query(1, k - 1);
} void Update(Data& data)
{
a->Update(data.Val, data.Index);
} long long Query(Data& data)
{
return a->Query(data.Val - 1, Range_GetIdGreaterCnt, data.Index) +
a->Query(MaxVal, Range_GetIdLesserCnt, data.Index) - a->Query(data.Val, Range_GetIdLesserCnt, data.Index);
} int main()
{
scanf("%d%d", &TotIndex, &TotDelCnt);
MaxVal = TotIndex;
static int Match[MAX_INDEX];
for (int i = 1; i <= TotIndex; i++)
{
_datas[i].Index = i;
scanf("%d", &_datas[i].Val);
Match[_datas[i].Val] = i;
}
int addTime = TotDelCnt;
for (int i = 1; i <= TotDelCnt; i++)
{
int delId;
scanf("%d", &delId);
_datas[Match[delId]].AddTime = addTime--;
} sort(_datas + 1, _datas + TotIndex + 1);
a = new BinaryTree(MaxVal);
long long tempAns = 0;
for (int i = 1; i <= TotIndex - TotDelCnt; i++)
{
Update(_datas[i]);
tempAns += Query(_datas[i]);
}
for (int i = TotIndex - TotDelCnt + 1; i <= TotIndex; i++)
{
Update(_datas[i]);
Ans[_datas[i].AddTime] = tempAns += Query(_datas[i]);
} for (int i = TotDelCnt; i >= 1; i--)
printf("%lld\n", Ans[i]);
return 0;
}
luogu3157 动态逆序对的更多相关文章
- BZOJ 3295: [Cqoi2011]动态逆序对
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3865 Solved: 1298[Submit][Sta ...
- Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2886 Solved: 924[Submit][Stat ...
- 【Luogu1393】动态逆序对(CDQ分治)
[Luogu1393]动态逆序对(CDQ分治) 题面 题目描述 对于给定的一段正整数序列,我们定义它的逆序对的个数为序列中ai>aj且i < j的有序对(i,j)的个数.你需要计算出一个序 ...
- 【BZOJ3295】动态逆序对(线段树,树状数组)
[BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...
- bzoj3295[Cqoi2011]动态逆序对 树套树
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5987 Solved: 2080[Submit][Sta ...
- cdq分治(hdu 5618 Jam's problem again[陌上花开]、CQOI 2011 动态逆序对、hdu 4742 Pinball Game、hdu 4456 Crowd、[HEOI2016/TJOI2016]序列、[NOI2007]货币兑换 )
hdu 5618 Jam's problem again #include <bits/stdc++.h> #define MAXN 100010 using namespace std; ...
- P3157 [CQOI2011]动态逆序对(树状数组套线段树)
P3157 [CQOI2011]动态逆序对 树状数组套线段树 静态逆序对咋做?树状数组(别管归并QWQ) 然鹅动态的咋做? 我们考虑每次删除一个元素. 减去的就是与这个元素有关的逆序对数,介个可以预处 ...
- P3157 [CQOI2011]动态逆序对
P3157 [CQOI2011]动态逆序对 https://www.luogu.org/problemnew/show/P3157 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai&g ...
- 2018.07.01 BZOJ3295: [Cqoi2011]动态逆序对(带修主席树)
3295: [Cqoi2011]动态逆序对 **Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j& ...
随机推荐
- Laravel5.1学习笔记11 系统架构3 服务提供者
服务提供者 简介 写一个服务提供者 Register注册方法 Boot 方法 注册提供者 缓载提供者 简介 Service providers are the central place of all ...
- 项目管理01--使用Maven构建项目(纯干货)
目录 1. Maven基础知识 2. Maven实战.开发.测试.打包.部署一个Web项目 一.Maven基础知识 Maven坐标 Maven提供了一个中央仓库,里面包含了大量的开源软件的jar包,只 ...
- Zabbix 客户端安装教程(第二篇)
Zabbix 客户端安装教程 blog地址:http://www.cnblogs.com/caoguo [root@localhost ~]# yum install -y gcc make [roo ...
- Java中接口与接口和类之间的关系
接口和接口之间的关系 继承关系 可以多继承,并且可以多层继承 注意: 1.如果多个父接口中有同名的抽象方法,那么子接口只需要实现一次即可 2.如果多个父接口中有同名的默认方法,那么子接口必须重写默认方 ...
- 利用shell脚本去备份幸运28源码搭建下载所指定的数据库
#! /bin/bash幸运28源码搭建下载Q[115288oo99]logintool=/home/yx/server/mysql/mysql/bin/mysqldumptool=/home/yx/ ...
- mitmproxy安装与使用
mitmproxy安装与使用 (抓包,中间人代理工具.支持SSL) 在开发微信公端的时候开发调试只能用浏览器自带开发工具,本来移动端可以用用fiddler.wireshark等工具来抓包,但是自从改用 ...
- Mapreduce代码疑点(1)
一.Hadoop MultipleInputs.addInputPath 读取多个路径 https://blog.csdn.net/t1dmzks/article/details/76473905 M ...
- CentOS安装Docker-ce并配置国内镜像
前提条件 1.系统.内核 CentOS7 要求64位系统.内核版本3.10以上 CentOS6 要求版本在6.5以上,系统64位.内核版本2.6.32-431以上 查看内核版本号 uname -r # ...
- [luogu3155 CQOI2009] 叶子的染色(树形dp)
传送门 Solution 十分简单的树形dpQwQ,转移关系:父亲染了儿子不用染 只需要确定根就是简单树形dp,而其实根可以随便取一个非叶子节点 可以分情况讨论发现答案并不会改变 Code //By ...
- python爬虫14 | 就这么说吧,如果你不懂python多线程和线程池,那就去河边摸鱼!
你知道吗? 在我的心里 你是多么的重要 就像 恩 请允许我来一段 freestyle 你们准备好了妹油 你看 这个碗 它又大又圆 就像 这条面 它又长又宽 你们 在这里 看文章 觉得 很开心 就像 我 ...