http://www.lydsy.com/JudgeOnline/problem.php?id=4889

人傻常数大 bzoj上跑不过 洛谷上能过两到三个点

我写的是树套树啊 怎么跑的比分块还慢

每次可以发现交换两个点 只对他们中间的点有影响 所以我们只用计算比x小的数的和 比x大的数的和 比y小的数的和 比y大的数的和 然后计算一下就可以了 很明显可以用各种数据结构维护

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = ;
const ll mod = ;
int n, m, cnt;
ll ans;
int q[N];
inline int read()
{
int x = , f = ; char c = getchar();
while(c < '' || c > '')
{
if(c == '-') f = -;
c = getchar();
}
while(c >= '' && c <= '')
{
x = x * + c - '';
c = getchar();
}
return x * f;
}
struct BIT {
ll tree[N], count[N];
int lowbit(int i)
{
return i & (-i);
}
void update(int pos, ll delta)
{
for(int i = pos; i <= ; i += lowbit(i))
{
tree[i] = (tree[i] + delta) % mod;
++count[i];
}
}
ll query(int pos, ll delta)
{
ll ret1 = , ret2 = ;
for(int i = pos; i; i -= lowbit(i))
{
ret1 = (ret1 + tree[i]) % mod;
ret2 += count[i];
}
ret1 = (ret1 + ret2 * delta) % mod;
return ret1;
}
} B;
struct data {
int a;
ll v;
} tree[N], a[N];
namespace splaytree
{
int fa[N], child[N][], root[N];
ll size[N], num[N], sum[N];
void update(int x)
{
size[x] = num[x] + size[child[x][]] + size[child[x][]];
sum[x] = (tree[x].v * num[x] + sum[child[x][]] + sum[child[x][]]) % mod;
}
void zig(int x)
{
int y = fa[x];
fa[x] = fa[y];
child[fa[x]][child[fa[x]][] == y] = x;
child[y][] = child[x][];
fa[child[x][]] = y;
fa[y] = x;
child[x][] = y;
update(y);
update(x);
}
void zag(int x)
{
int y = fa[x];
fa[x] = fa[y];
child[fa[x]][child[fa[x]][] == y] = x;
child[y][] = child[x][];
fa[child[x][]] = y;
fa[y] = x;
child[x][] = y;
update(y);
update(x);
}
void splay(int x, int t, int pos)
{
while(fa[x] != t)
{
int y = fa[x], z = fa[y];
if(z == t)
{
child[y][] == x ? zig(x) : zag(x);
break;
}
else if(y == child[z][] && x == child[y][]) { zig(y); zig(x); }
else if(y == child[z][] && x == child[y][]) { zag(y); zag(x); }
else if(y == child[z][] && x == child[y][]) { zag(x); zig(x); }
else if(y == child[z][] && x == child[y][]) { zig(x); zag(x); }
}
if(!t) root[pos] = x;
update(root[pos]);
}
void up(int x)
{
while(x)
{
update(x);
x = fa[x];
}
}
ll getbig(int pos, data &k)
{
int now = root[pos];
ll ret = ;
while(now)
{
if(tree[now].a > k.a)
{
ret = (ret + k.v + tree[now].v) % mod;
ret = (ret + k.v * size[child[now][]] +
sum[child[now][]]) % mod;
now = child[now][];
}
else now = child[now][];
}
return ret;
}
ll getsmall(int pos, data &k)
{
int now = root[pos];
ll ret = ;
while(now)
{
if(tree[now].a < k.a)
{
ret = (ret + k.v + tree[now].v) % mod;
ret = (ret + k.v * size[child[now][]] +
sum[child[now][]]) % mod;
now = child[now][];
}
else now = child[now][];
}
return ret;
}
int find(int x, data &k)
{
for(x = root[x]; x; x = child[x][k.a > tree[x].a])
if(tree[x].a == k.a) return x;
}
void del(int pos, int x)
{
splay(x, , pos);
if(num[x] > )
{
--num[x];
update(x);
return;
}
if(child[x][] * child[x][] == )
{
root[pos] = child[x][] + child[x][];
fa[root[pos]] = ;
child[x][] = child[x][] = fa[x] = ;
return;
}
int now = child[x][];
while(child[now][]) now = child[now][];
fa[child[x][]] = now;
child[now][] = child[x][];
root[pos] = child[x][];
fa[root[pos]] = ;
up(child[x][]);
child[x][] = child[x][] = num[x] = size[x]
= fa[x] = ;
splay(now, , pos);
}
void insert(int pos, data &k)
{
int now = root[pos];
if(!root[pos])
{
root[pos] = ++cnt;
tree[cnt] = k;
size[cnt] = num[cnt] = ;
sum[cnt] = k.v;
return;
}
while()
{
if(tree[now].a == k.a)
{
++num[now];
up(now);
break;
}
if(!child[now][k.a > tree[now].a])
{
child[now][k.a > tree[now].a] = ++cnt;
tree[cnt] = k;
size[cnt] = num[cnt] = ;
fa[cnt] = now;
sum[cnt] = k.v;
up(cnt);
splay(cnt, , pos);
break;
}
now = child[now][k.a > tree[now].a];
}
}
} using namespace splaytree;
namespace segmenttree
{
void update(int l, int r, int x, int pos, data &k)
{
if(l == r)
{
root[x] = ++cnt;
tree[cnt] = k;
num[cnt] = size[cnt] = ;
sum[cnt] = k.v;
return;
}
int mid = (l + r) >> ;
if(pos <= mid) update(l, mid, x << , pos, k);
else update(mid + , r, x << | , pos, k);
int t = find(x, a[pos]);
del(x, t); insert(x, k);
}
void build(int l, int r, int x)
{
if(l == r)
{
root[x] = ++cnt;
num[cnt] = size[cnt] = ;
tree[cnt] = a[l];
sum[cnt] = a[l].v;
return;
}
int mid = (l + r) >> ;
build(l, mid, x << );
build(mid + , r, x << | );
for(int i = l; i <= r; ++i) insert(x, a[i]);
}
ll querybig(int l, int r, int x, int a, int b, data &k)
{
if(l > b || r < a) return ;
if(l >= a && r <= b) return getbig(x, k) % mod;
int mid = (l + r) >> ;
return ((querybig(l, mid, x << , a, b, k) +
querybig(mid + , r, x << | , a, b, k)) % mod);
}
ll querysmall(int l, int r, int x, int a, int b, data &k)
{
if(l > b || r < a) return ;
if(l >= a && r <= b) return getsmall(x, k) % mod;
int mid = (l + r) >> ;
return ((querysmall(l, mid, x << , a, b, k) +
querysmall(mid + , r, x << | , a, b, k)) % mod);
}
} using namespace segmenttree;
int main()
{
n = read(); m = read();
for(int i = ; i <= n; ++i)
{
a[i].a = read(); a[i].v = read();
ans = ((ans + B.query(, a[i].v) - B.query(a[i].a, a[i].v)) % mod + mod) % mod;
B.update(a[i].a, a[i].v);
}
build(, n, );
while(m--)
{
int x, y; x = read(); y = read();
if(x > y) swap(x, y);
if(x == y)
{
printf("%lld\n", ans);
continue;
}
if(a[x].a < a[y].a) ans += a[x].v + a[y].v;
else ans -= a[x].v + a[y].v;
ll a1 = querybig(, n, , x + , y - , a[x]);
ll a2 = querysmall(, n, , x + , y - , a[x]);
ll a3 = querysmall(, n, , x + , y - , a[y]);
ll a4 = querybig(, n, , x + , y - , a[y]);
ans = ((ans + a1 - a2 + a3 - a4) % mod + mod) % mod;
update(, n, , x, a[y]);
update(, n, , y, a[x]);
swap(a[x], a[y]);
printf("%lld\n", ans);
}
return ;
}

bzoj4889的更多相关文章

  1. 【BZOJ4889】不勤劳的图书管理员(树套树)

    [BZOJ4889]不勤劳的图书管理员(树套树) 题面 又是权限题,烦死了 洛谷真好 题解 分开考虑每一次交换产生的贡献. 假设交换\((x,y)\) 检查\(x\)与\(y\)对于区间\([x+1, ...

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

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

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

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

  4. BZOJ4889 & 洛谷3759:[TJOI2017]不勤劳的图书管理员——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4889 https://www.luogu.org/problemnew/show/P3759 加里 ...

  5. [bzoj4889] [Tjoi2017]不勤劳的图书管理员

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

  6. [TJOI2017][bzoj4889] 不勤劳的图书管理员 [线段树套线段树]

    题面 传送门 思路 考虑两本书的位置交换对答案的贡献: (为了方便描述,用"左边那本"和"右边那本"称呼两本我们要交换的书,"中间那本"是我 ...

  7. BZOJ4889:[TJOI2017]不勤劳的图书管理员

    浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html 题目传送门:https://www.lydsy.com/JudgeOnline/prob ...

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

    传送门 据说正解线段树套平衡树 然而网上参考(抄)了一个树状数组套动态开点线段树的 思路比较清楚,看代码应该就明白了 //minamoto #include<iostream> #incl ...

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

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

随机推荐

  1. JAVA I/O之文件复制

    有没有大佬告诉我这个不要了的代码插入区(就现在这句话的区域)怎么删掉....... //一个字节一个字节的复制 public static void fun() throws IOException ...

  2. Spring Boot 缓存的基本用法

    目录 一.目的 二.JSR-107 缓存规范 三.Spring 缓存抽象 四.Demo 1.使用 IDEA 创建 Spring Boot 项目 2.创建相应的数据表 3.创建 Java Bean 封装 ...

  3. UVA - 10723 Cyborg Genes (LCS)

    题目: 思路: 求两个串的最长公共子序列,则这个最短的串就是给出的两个串的长度和减去最长公共子序列的长度. 状态转移方程: 如果s[i-1]==t[j-1]就有dp[i][j] = dp[i-1][j ...

  4. X shell 6下载安装和简单使用

    ①前言:昨天已经上线了的智能家居项目出现了一个BUG,需要重新写个html发布到服务器上,由于公司大佬都在忙别的项目,时间比较紧张,这种小事就落到了我这个小喽啰身上.其实,写个html我还是可以接受的 ...

  5. FZU 1492 地震预测(模拟链表的应用)(Java实现)

    FZU 1492 地震预测(模拟链表的应用)(Java实现) 怀特先生是一名研究地震的科学家,最近他发现如果知道某一段时间内的地壳震动能量采样的最小波动值之和,可以有效地预测大地震的发生. 假设已知一 ...

  6. PAT 1122 Hamiltonian Cycle

    The "Hamilton cycle problem" is to find a simple cycle that contains every vertex in a gra ...

  7. 50. Spring Boot日志升级篇—log4j【从零开始学Spring Boot】

    如果你使用的是spring boot 1.4.0版本的话,那么你可能需要配合以下文章进行学习 90.Spring Boot 1.4 使用log4j错误[从零开始学Spring Boot] Log4j是 ...

  8. nyoj_116_士兵杀敌(二)_201404131107

    士兵杀敌(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:5   描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常 ...

  9. 混合图(dizzy.pas/cpp/c)

    混合图(dizzy.pas/cpp/c) [题目描述] Hzwer神犇最近又征服了一个国家,然后接下来却也遇见了一个难题. Hzwer的国家有n个点,m条边,而作为国王,他十分喜欢游览自己的国家.他一 ...

  10. Ubuntu 16.04设置开机启动应用程序

    在终端通过以下命令进行设置,Dash已经搜索不到Startup了: gnome-session-properties 或者直接在Dash中搜索:gnome-session