树套树是什么啊我不知道/dk

我只知道卡常数w

// by Isaunoya
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize( \
"inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2,-ffast-math,-fsched-spec,unroll-loops,-falign-jumps,-falign-loops,-falign-labels,-fdevirtualize,-fcaller-saves,-fcrossjumping,-fthread-jumps,-funroll-loops,-freorder-blocks,-fschedule-insns,inline-functions,-ftree-tail-merge,-fschedule-insns2,-fstrict-aliasing,-fstrict-overflow,-falign-functions,-fcse-follow-jumps,-fsched-interblock,-fpartial-inlining,no-stack-protector,-freorder-functions,-findirect-inlining,-fhoist-adjacent-loads,-frerun-cse-after-loop,inline-small-functions,-finline-small-functions,-ftree-switch-conversion,-foptimize-sibling-calls,-fexpensive-optimizations,inline-functions-called-once,-fdelete-null-pointer-checks")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
#define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
using ll = long long;
const int _ = 1 << 21;
struct I {
char fin[_], *p1 = fin, *p2 = fin;
inline char gc() {
return (p1 == p2) && (p2 = (p1 = fin) + fread(fin, 1, _, stdin), p1 == p2) ? EOF : *p1++;
}
inline I& operator>>(int& x) {
bool sign = 1;
char c = 0;
while (c < 48) ((c = gc()) == 45) && (sign = 0);
x = (c & 15);
while ((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15);
x = sign ? x : -x;
return *this;
}
inline I& operator>>(double& x) {
bool sign = 1;
char c = 0;
while (c < 48) ((c = gc()) == 45) && (sign = 0);
x = (c - 48);
while ((c = gc()) > 47) x = x * 10 + (c - 48);
if (c == '.') {
double d = 1.0;
while ((c = gc()) > 47) d = d * 0.1, x = x + (d * (c - 48));
}
x = sign ? x : -x;
return *this;
}
inline I& operator>>(char& x) {
do
x = gc();
while (isspace(x));
return *this;
}
inline I& operator>>(string& s) {
s = "";
char c = gc();
while (isspace(c)) c = gc();
while (!isspace(c) && c != EOF) s += c, c = gc();
return *this;
}
} in;
struct O {
char st[100], fout[_];
signed stk = 0, top = 0;
inline void flush() { fwrite(fout, 1, top, stdout), fflush(stdout), top = 0; }
inline O& operator<<(int x) {
if (top > (1 << 20))
flush();
if (x < 0)
fout[top++] = 45, x = -x;
do
st[++stk] = x % 10 ^ 48, x /= 10;
while (x);
while (stk) fout[top++] = st[stk--];
return *this;
}
inline O& operator<<(ll x) {
if (top > (1 << 20))
flush();
if (x < 0)
fout[top++] = 45, x = -x;
do
st[++stk] = x % 10 ^ 48, x /= 10;
while (x);
while (stk) fout[top++] = st[stk--];
return *this;
}
inline O& operator<<(char x) {
fout[top++] = x;
return *this;
}
inline O& operator<<(string s) {
if (top > (1 << 20))
flush();
for (char x : s) fout[top++] = x;
return *this;
}
} out;
#define pb emplace_back
#define fir first
#define sec second
template <class T>
inline void cmax(T& x, const T& y) {
(x < y) && (x = y);
}
template <class T>
inline void cmin(T& x, const T& y) {
(x > y) && (x = y);
}
const int N = 5e4 + 10;
const int mod = 1e9 + 7;
int n, m, a[N], v[N], rt[N], ls[N << 8], rs[N << 8], Cnt = 0;
struct SegMent {
int val[N << 8];
void upd(int& p, int l, int r, int pos, int v) {
if (!p)
p = ++Cnt;
val[p] += v;
if (l == r)
return;
int mid = l + r >> 1;
(pos <= mid) ? upd(ls[p], l, mid, pos, v) : upd(rs[p], mid + 1, r, pos, v);
}
int qry(int p, int a, int b, int l, int r) {
if (!p)
return 0;
if (a <= l && r <= b)
return val[p];
int mid = l + r >> 1, ans = 0;
if (a <= mid)
ans = qry(ls[p], a, b, l, mid);
if (b > mid)
ans += qry(rs[p], a, b, mid + 1, r);
return ans % mod;
}
inline int low(const int& x) { return x & -x; }
inline void upd(int x, int y, int k) {
for (; x <= n; x += low(x)) upd(rt[x], 1, n, y, k);
}
inline ll qry(int l, int r, int a, int b) {
ll ans = 0;
for (; r; r ^= low(r)) {
ans = (ans + qry(rt[r], a, b, 1, n)) % mod;
}
for (--l; l; l ^= low(l)) {
ans = (ans - qry(rt[l], a, b, 1, n) + mod) % mod;
}
return ans;
}
} cnt, qwq;
ll ans = 0;
signed main() {
#ifdef _WIN64
freopen("testdata.in", "r", stdin);
#endif
in >> n >> m;
rep(i, 1, n) in >> a[i] >> v[i];
rep(i, 1, n) cnt.upd(i, a[i], 1), qwq.upd(i, a[i], v[i]);
rep(i, 1, n) {
ans = (ans + cnt.qry(i + 1, n, 1, a[i]) * v[i]) % mod;
ans = (ans + qwq.qry(i + 1, n, 1, a[i])) % mod;
}
while (m--) {
int x, y;
in >> x >> y;
if (x > y)
swap(x, y);
if (x == y) {
out << ans << '\n';
continue;
}
ans = (ans +
(a[x] < a[y] ? 1 : -1) *
(2 * qwq.qry(x, y, min(a[x], a[y]) + 1, max(a[x], a[y]) - 1) +
(cnt.qry(x, y, min(a[x], a[y]) + 1, max(a[x], a[y]) - 1) + 1) * (v[x] + v[y])) %
mod +
mod) %
mod;
ans = (ans + cnt.qry(x, y, 1, min(a[x], a[y]) - 1) * (v[y] - v[x]) % mod + mod) % mod;
ans = (ans + cnt.qry(x, y, max(a[x], a[y]) + 1, n) * (v[x] - v[y]) % mod + mod) % mod;
cnt.upd(x, a[x], -1), qwq.upd(x, a[x], -v[x]);
cnt.upd(y, a[y], -1), qwq.upd(y, a[y], -v[y]);
cnt.upd(x, a[y], 1), qwq.upd(x, a[y], v[y]);
cnt.upd(y, a[x], 1), qwq.upd(y, a[x], v[x]);
swap(a[x], a[y]), swap(v[x], v[y]);
out << ans << '\n';
}
return out.flush(), 0;
}

P3759 [TJOI2017]不勤劳的图书管理员 [树套树]的更多相关文章

  1. 洛谷P3759 - [TJOI2017]不勤劳的图书管理员

    Portal Description 给出一个\(1..n(n\leq5\times10^4)\)的排列\(\{a_n\}\)和数列\(\{w_n\}(w_i\leq10^5)\),进行\(m(m\l ...

  2. [TJOI2017]不勤劳的图书管理员(分块+树状数组)

    有一个数组开大会MLE开小会RE的做法:就是树套树,即树状数组套主席树,这种方法比较暴力,然而很遗憾它不能通过,因为其时空复杂度均为O(nlog2n). 想到一种不怎么耗内存,以时间换空间,分块!单次 ...

  3. [P3759][TJOI2017]不勤劳的图书管理员(分块+树状数组)

    题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生 这两本书页数的和的厌烦度.现在有n本被打乱顺序的书 ...

  4. 洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】

    题目链接 洛谷P3759 题解 树状数组套主席树板题 #include<algorithm> #include<iostream> #include<cstring> ...

  5. LUOGU P3759 [TJOI2017]不勤劳的图书管理员(树套树)

    传送门 解题思路 和以前做过的一道题有点像,就是区间逆序对之类的问题,用的是\(BIT\)套权值线段树,交换时讨论一下计算答案..跑的不如暴力快.. 代码 #include<iostream&g ...

  6. 【BZOJ4889】[Tjoi2017]不勤劳的图书管理员 分块+树状数组

    [BZOJ4889][Tjoi2017]不勤劳的图书管理员 题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让 ...

  7. 【bzoj4889】: [Tjoi2017]不勤劳的图书管理员 分块-BIT

    [bzoj4889]: [Tjoi2017]不勤劳的图书管理员 题目大意:给定一个序列(n<=50000),每个数有一个编码ai(ai<=50000)和权值vi(vi<=100000 ...

  8. 4889: [Tjoi2017]不勤劳的图书管理员 树套树

    国际惯例的题面(Bzoj没有,洛谷找的):动态加权逆序对,一眼树套树.256MB内存,5e4范围,不虚不虚.首先把交换改成两个插入和两个删除.考虑插入和删除的贡献,就是统计前面比这个值大的数的数值和, ...

  9. 【洛谷3759】[TJOI2017] 不勤劳的图书管理员(树套树)

    点此看题面 大致题意: 给定一个序列,每个元素有两个属性\(a_i\)和\(v_i\),每次操作改变两个元素的位置,求每次操作后\(\sum{v_i+v_j}[i<j,a_i>a_j]\) ...

随机推荐

  1. python之面向对象01

    1.面向过程编程最容易被初学者接受,其往往用一段长代码来实现指定功能,开发过程的思路是将数据与函数按照执行的逻辑顺序组织在一起,数据与函数分开考虑. 2.类与对象 (1)类是抽象的,是有相同属性和行为 ...

  2. 快速幂——while理解&&[P1965] 转圈游戏

    快速幂--while理解 \[a^k\] 把k转成2进制 \[k=2^n*p[n]+2^(n-1)*p[n-1]+...+2^1*p[1]+2^0*p[0]\] \[a^k=a^(2^n*p[n]+2 ...

  3. Postman之命令测试

    前言 今天我们来学习一下Postman的命令行测试 1.先安装node.js ,https://nodejs.org/en/#home-downloadhead 2.安装cnpm npm instal ...

  4. Docker Compose 模板文件 V2

    模板文件是使用Compose的核心,默认模板文件名称为docker-compose.yml ,格式为YAML格式. 目录结构 [root@localhost ~]# tree /opt/compose ...

  5. Spring——自动装配(@Autowired/@Profile/底层组件)

    本文介绍Spring中关于自动装配的方法和规则,以及@Profile动态激活的用法和一个例子. 一.@Autowired自动装配 @Autowired注解可以加在构造器.属性.方法.方法参数上. 自动 ...

  6. vue路由--命名视图

    有时候想同时(同级)展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar(侧导航) 和 main(主内容) 两个视图,这个时候命名视图就派上用场了.你可以在界面中拥有多个单独命名的视图, ...

  7. C语言基础五 数组

    数组跟变量的区别? 数组是可以在内存中连续存储多个元素的结构,所有元素必须属于相同类型. 格式:元素类型 数组名[元素个数]: 数组的特点: 只能存放单一元素的数据,里面存放的数据成为元素. 数组的声 ...

  8. C#建立自己的测试用例系统

    引言 很多时候,需要对类中的方法进行一些测试,来判断是否能按要求输出预期的结果. C#提供了快速创建单元测试的方法,但单元测试不仅速度慢不方便,大量的单元测试还会拖慢项目的启动速度. 所以决定自己搞个 ...

  9. 面试官:你用过mysql哪些存储引擎,请分别展开介绍一下

    这是高级开发者面试时经常被问的问题.实际我们在平时的开发中,经常会遇到的,在用SQLyog等工具创建表时,就有一个引擎项要你去选.如下图: Mysql的存储引擎有这么多种,实际我们在平时用的最多的莫过 ...

  10. 记一次Postgres CPU爆满故障

    问题描述 公司项目测试环境调用某些接口的时候,服务器立即崩溃,并一定时间内无法提供服务. 问题排查 服务器配置不够 第一反应是服务器需要升配啦,花钱解决一切!毕竟测试服务器配置确实不高,2CPU + ...