P2448 无尽的生命
Description
小 a有一个长度无限长的序列 p = (1, 2, 3, 4 ……),初始时 pi = i
给出 m 个操作,每次交换两个位置的数
询问最后序列逆序对的个数
Solution
忘了可以树状数组直接做了.所以写了很麻烦的线段树.
大概写一下怎么做, 因为细节比较多.
我们发现一次交换的实际上是交换了两个位置上的数.
我们可以将所有的位置分成三类:
有的位置会被改变(交换), 也对答案有贡献;
有的位置不会被改变, 也不会对答案有贡献;
有的位置不会被改变, 但是对答案有贡献.
第一类是所有的操作会交换的位置;
第二类是被改变的第一个和最后一个位置往左和往右的数;
第三类是不会被直接改变, 但是其左右都有被改变的数.
举个例子:交换2和5位置, 数列变成\(1,5,3,4,2,6,7,\cdots\).
位置\(2, 5\)属于第一类, 位置\(1,6,7,\cdots\)属于第二类, 位置\(3, 4\)属于第三类(因为与5位置形成逆序对)
- 对于不会被改变也没有影响的数, 忽略存在就好了.
- 对于不会被改变但是有影响的位置, 这些位置的行为表现出来像是一个整体(会同时对另一个位置产生或不产生逆序对).
所以就把他们捆起来, 看成是一个特殊的数字就好了.
所以就将这些涉及到的位置离散化, 在离散化后按要求交换这些位置上的数形成一个数列,利用树状数组/线段树求逆序对即可.
至于怎么离散化, 看代码就好了
Code
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e6;
struct Node {
long long val;
Node *ls, *rs;
Node(int _v = 0, Node *_ls = nullptr, Node *_rs = nullptr) :
val(_v), ls(_ls), rs(_rs) { }
void pushup() {
val = ls->val + rs->val;
}
void mod(int k) { val += k; }
};
class Tree { // 普通的单调修改区间查询线段树
int n;
Node* root;
#define LS l, mid, node->ls
#define RS mid + 1, r, node->rs
void build(int l, int r, Node* node) {
if (l == r) return;
int mid = l + r >> 1;
node->ls = new Node();
node->rs = new Node();
build(LS), build(RS);
}
void insert(int l, int r, Node* node, int p, int k) {
if (l == r) return node->mod(k);
int mid = l + r >> 1;
if (p <= mid) insert(LS, p, k);
if (p > mid) insert(RS, p, k);
node->val = node->ls->val + node->rs->val;
}
long long query(int l, int r, Node* node, int L, int R) {
if (l >= L and r <= R)
return node->val;
int mid = l + r >> 1;
long long res = 0;
if (L <= mid) res += query(LS, L, R);
if (R > mid) res += query(RS, L, R);
return res;
}
public:
Tree(int _n) : n(_n), root(new Node()) {}
void build() {
build(1, n, root);
}
long long query(int l, int r) {
return query(1, n, root, l, r);
}
void insert(int p, int k) {
insert(1, n, root, p, k);
}
};
struct Operate {
int l, r;
Operate(int _ = 0, int __ = 0) :
l(_), r(__) {}
}Opt[N];
struct Element {
int v, siz;
Element(int _v = 0, int _s = 0) :
v(_v), siz(_s) { }
bool operator < (const Element& o) const {
return v < o.v;
}
}P[N];
int A[N], seq[N];
int main () {
int n;
scanf("%d", &n);
int tot = 0;
for (int i = 1, u, v, c; i <= n; i += 1) {
scanf("%d%d", &u, &v);
Opt[i] = Operate(u, v);
A[++tot] = u, A[++tot] = v;
}
sort(A + 1, A + tot + 1);
int cnt = unique(A + 1, A + tot + 1) - A - 1; // 被直接交换的位置, 也就是第一类
int total = 0;
for (int i = 1; i <= cnt; i += 1) {
P[++total] = Element(A[i], 1); // 第一类
if (A[i + 1] > A[i] + 1) // A[i] 和A[i+1]之间的是第三类
P[++total] = Element(A[i] + 1, A[i + 1] - A[i] - 1); // A[i+1]-A[i]-1是这一段的个数
}
#define Find(x) lower_bound(P + 1, P + total + 1, Element(x, 0)) - P
Tree* T = new Tree(total); // 建线段树
T->build();
for (int i = 1; i <= total; i += 1)
seq[i] = i;
for (int i = 1, u, v; i <= n; i += 1) {
u = Find(Opt[i].l), v = Find(Opt[i].r); // 按要求交换
swap(seq[u], seq[v]);
}
long long res = 0;
for (int i = 1; i <= total; i += 1) {
T->insert(seq[i], P[seq[i]].siz);
res += 1ll * P[seq[i]].siz * T->query(seq[i] + 1, total);
}
printf("%lld\n", res);
return 0;
}
P2448 无尽的生命的更多相关文章
- P2448 无尽的生命(树状数组+离散化)
题目描述 逝者如斯夫,不舍昼夜! 叶良辰认为,他的寿命是无限长的,而且每天都会进步. 叶良辰的生命的第一天,他有1点能力值.第二天,有2点.第n天,就有n点.也就是S[i]=i 但是调皮的小A使用时光 ...
- 杂项 List
题目 1. 栈 #A 表达式的转换 (Unaccepted) 2. STL 模板库 #B 双栈排序(Unaccepted) #C 垃圾陷阱(Accepted) #D 合并果子(Acc ...
- Linux内核同步
Linux内核剖析 之 内核同步 主要内容 1.内核请求何时以交错(interleave)的方式执行以及交错程度如何. 2.内核所实现的基本同步机制. 3.通常情况下如何使用内核提供的同步机制. 内核 ...
- Unity脚本生命周期
前言 说到生命周期,影响最深刻的是,在接触Java的JSF组件时,JSF组件的五大生命周期,全要默写出来,嘿嘿…… 总结这两天在写小怪和掉落的糖葫芦时,老是遇到GameObject未销毁,一直存在场景 ...
- GPU大百科全书 第二章 凝固生命的光栅化
光栅化——死神来了…… 前言:在上一期的GPU大百科全书里,我们目睹了可爱的香草从抽象世界走向现实,从方程还原成实体的全过程.可以说香草活了,因为几何单元,我们赋予了她完整的灵魂. 如果你正在为G ...
- 从BeanFactory源码看Bean的生命周期
下图是我搜索"Spring Bean生命周期"找到的图片,来自文章--Spring Bean的生命周期 下面,我们从AbstractAutowireCapableBeanFacto ...
- react组件的生命周期
写在前面: 阅读了多遍文章之后,自己总结了一个.一遍加强记忆,和日后回顾. 一.实例化(初始化) var Button = React.createClass({ getInitialState: f ...
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
- C# MVC 5 - 生命周期(应用程序生命周期&请求生命周期)
本文是根据网上的文章总结的. 1.介绍 本文讨论ASP.Net MVC框架MVC的请求生命周期. MVC有两个生命周期,一为应用程序生命周期,二为请求生命周期. 2.应用程序生命周期 应用程序生命周期 ...
随机推荐
- WEB入门.七 CSS布局模型
学习内容 标准文档流 流动模型(flow model) 浮动模型(float model) CSS基本布局 能力目标 理解标准文档流 使用流动模型实现页面布局 使用浮动模型实现页面布局 掌握常用CSS ...
- (二)C语言文本流和二进制流的区别
转至:http://www.cnblogs.com/xiangzi888/archive/2011/11/10/2244336.html 一.首先回答,什么是文件,流 一个文件通常就是磁盘上的一段命名 ...
- poj 3415 后缀数组 两个字符串中长度不小于 k 的公共子串的个数
Common Substrings Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 11469 Accepted: 379 ...
- Python【网络编程】内置模块urllib
from urllib import request,parseurl = 'http://www.nnzhp.cn'req = request.urlopen(url) #打开一个url,发get请 ...
- Hadoop生态圈-HBase的HFile创建方式
Hadoop生态圈-HBase的HFile创建方式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 废话不多说,直接上代码,想说的话都在代码的注释里面. 一.环境准备 list cr ...
- PHP常见数组方法和函数
current();当前游标指向的数组单元值 next();下一个数组单元值 end()最后一个 reset()复位 prev()把数组指针往前一位 写法:$arr=array('a','b','c' ...
- 京东全链路压测军演系统(ForceBot)架构解密
摘要:全链路压测是应对电商大促容量规划最有效的手段,如何有效进行容量规划是其中的架构关键问题.京东在全链路压测方面做过多年尝试,本文转载京东商城基础平台技术专家文章,介绍其最新的自动化压测 Force ...
- Java入门系列(一)基础概览
序言 Java语言的特点不使用指针而使用引用.
- 2.批处理内部命令之REM 和::
REM为注释命令,一般用来给程序加上注解,该命令后的内容不被执行,但能回显. 另外, :: 也可以起到rem 的注释作用, 而且更简洁有效; 但有两点需要注意: 1. 任何以冒号:开头的字符行, 在批 ...
- R6—单变量正态性检验
方法不唯一 单变量正态检验主要的话包括以下这些 shapiro.test();#Shapiro-Wilk检验 library("nortest"); lillie.test() # ...