【BZOJ4889】[Tjoi2017]不勤劳的图书管理员 分块+树状数组
【BZOJ4889】[Tjoi2017]不勤劳的图书管理员
题目描述
加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员。他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度。现在有n本被打乱顺序的书,在接下来m天中每天都会因为读者的阅览导致书籍顺序改变位置。因为小豆被要求在接下来的m天中至少要整理一次图书。小豆想知道,如果他前i天不去整理,第i天他的厌烦度是多少,这样他好选择厌烦度最小的那天去整理。
输入输出格式
输入格式:
第一行会有两个数,n,m分别表示有n本书,m天
接下来n行,每行两个数,ai和vi,分别表示第i本书本来应该放在ai的位置,这本书有vi页,保证不会有放置同一个位置的书
接下来m行,每行两个数,xj和yj,表示在第j天的第xj本书会和第yj本书会因为读者阅读交换位置
输出格式:
一共m行,每行一个数,第i行表示前i天不去整理,第i天小豆的厌烦度,因为这个数可能很大,所以将结果模10^9 +7后输出
输入输出样例
5 5
1 1
2 2
3 3
4 4
5 5
1 5
1 5
2 4
5 3
1 3
42
0
18
28
48
说明
对于20%的数据,1 ≤ ai; xj; yj ≤ n ≤ 5000, m ≤ 5000, vi ≤ 10^5
对于100%的数据,1 ≤ ai; xj; yj ≤ n ≤ 50000, m ≤ 50000, vi ≤ 10^5
题解:其实就是让你求一个区间中的带权逆序对数,依然用分块。对于每个块,维护两个树状数组s1,s2。s1代表书的个数,s2代表书的页数的前缀和。修改的时候,只有l,r和(l,r)中的数间的逆序对会改变,两边的不会改变。所以先暴力判断连边的小块,再扫中间的大块。设块的大小为B,假设一个块中有num本书的a值比l小,这些数的页数和为sum,那么ans-=sum-(B-num)*v[l]。r类似。
结果一交上去TLE了,实测109s多,改了一下块的大小就60s了。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn=50010;
const ll mod=1000000007;
ll ans;
int n,m,B;
ll s[2][250][maxn],v[maxn];
int p[maxn];
int rd()
{
int ret=0; char gc=getchar();
while(gc<'0'||gc>'9') gc=getchar();
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret;
}
void updata(int z,int y,int x,ll val)
{
if(!x) return ;
for(int i=x;i<=n;i+=i&-i) s[z][y][i]=(s[z][y][i]+val+mod)%mod;
}
ll query(int z,int y,int x)
{
if(x<0) return 0;
ll ret=0;
for(int i=x;i;i-=i&-i) ret=(ret+s[z][y][i])%mod;
return ret;
}
void calc(int a,int b,int c)
{
if(p[a]<p[c]) ans=(ans+v[a]+v[c])%mod;
else ans=(ans-v[a]-v[c]+mod+mod)%mod;
if(p[b]<p[c]) ans=(ans-v[b]-v[c]+mod+mod)%mod;
else ans=(ans+v[b]+v[c])%mod;
}
int main()
{
int i,j,a,b,c,d;
n=rd(),m=rd(),B=int(sqrt(n*17));
for(i=0;i<n;i++) p[i]=rd(),v[i]=rd(),updata(0,i/B,p[i],v[i]),updata(1,i/B,p[i],1);
for(i=n-1;i>=0;i--)
{
ans=(ans+query(0,n/B+1,p[i])+query(1,n/B+1,p[i])*v[i])%mod;
updata(0,n/B+1,p[i],v[i]),updata(1,n/B+1,p[i],1);
}
for(i=1;i<=m;i++)
{
a=rd()-1,b=rd()-1;
if(a==b)
{
printf("%lld\n",ans);
continue;
}
if(a>b) swap(a,b);
c=a/B,d=b/B;
if(p[a]<p[b]) ans=(ans+v[a]+v[b])%mod;
else ans=(ans-v[a]-v[b]+mod+mod)%mod;
if(c==d)
{
for(j=a+1;j<b;j++) calc(a,b,j);
swap(p[a],p[b]),swap(v[a],v[b]);
printf("%lld\n",ans);
continue;
}
for(j=a+1;j<c*B+B;j++) calc(a,b,j);
for(j=d*B;j<b;j++) calc(a,b,j);
for(j=c+1;j<d;j++)
{
ans=(ans-2*query(0,j,p[a])+query(0,j,n)-(2*query(1,j,p[a])-B+mod)*v[a]%mod+mod)%mod;
ans=(ans+2*query(0,j,p[b])-query(0,j,n)+(2*query(1,j,p[b])-B+mod)*v[b]%mod+mod)%mod;
}
updata(0,c,p[a],-v[a]),updata(0,d,p[b],-v[b]),updata(1,c,p[a],-1),updata(1,d,p[b],-1);
swap(p[a],p[b]),swap(v[a],v[b]);
updata(0,c,p[a],v[a]),updata(0,d,p[b],v[b]),updata(1,c,p[a],1),updata(1,d,p[b],1);
printf("%lld\n",ans);
}
return 0;
}
//5 5 1 1 2 2 3 3 4 4 5 5 1 5 1 5 2 4 5 3 1 3
【BZOJ4889】[Tjoi2017]不勤劳的图书管理员 分块+树状数组的更多相关文章
- [P3759][TJOI2017]不勤劳的图书管理员(分块+树状数组)
题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生 这两本书页数的和的厌烦度.现在有n本被打乱顺序的书 ...
- 洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】
题目链接 洛谷P3759 题解 树状数组套主席树板题 #include<algorithm> #include<iostream> #include<cstring> ...
- bzoj4889: [Tjoi2017]不勤劳的图书管理员(树套树)
传送门 据说正解线段树套平衡树 然而网上参考(抄)了一个树状数组套动态开点线段树的 思路比较清楚,看代码应该就明白了 //minamoto #include<iostream> #incl ...
- 【BZOJ4889】不勤劳的图书管理员(树套树)
[BZOJ4889]不勤劳的图书管理员(树套树) 题面 又是权限题,烦死了 洛谷真好 题解 分开考虑每一次交换产生的贡献. 假设交换\((x,y)\) 检查\(x\)与\(y\)对于区间\([x+1, ...
- 【bzoj4889】: [Tjoi2017]不勤劳的图书管理员 分块-BIT
[bzoj4889]: [Tjoi2017]不勤劳的图书管理员 题目大意:给定一个序列(n<=50000),每个数有一个编码ai(ai<=50000)和权值vi(vi<=100000 ...
- [bzoj4889] [Tjoi2017]不勤劳的图书管理员
Description 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被 ...
- 【洛谷3759】[TJOI2017] 不勤劳的图书管理员(树套树)
点此看题面 大致题意: 给定一个序列,每个元素有两个属性\(a_i\)和\(v_i\),每次操作改变两个元素的位置,求每次操作后\(\sum{v_i+v_j}[i<j,a_i>a_j]\) ...
- 【loj2639】[Tjoi2017]不勤劳的图书管理员
#2639. 「TJOI2017」不勤劳的图书管理员 题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产 ...
- 洛谷P3759 - [TJOI2017]不勤劳的图书管理员
Portal Description 给出一个\(1..n(n\leq5\times10^4)\)的排列\(\{a_n\}\)和数列\(\{w_n\}(w_i\leq10^5)\),进行\(m(m\l ...
随机推荐
- MySQL连接本地数据库时报1045错误的解决方法
navicat for MySQL 连接本地数据库出现1045错误 如下图: 说明连接mysql时数据库密码错误,需要修改密码后才可解决问题: 解决步骤如下: .首先打开命令行:开始->运行 ...
- DirectX11与DirectX12在古墓丽影暗影中的表现
最近在关注这两个图形API,因为感兴趣,也算是初学者. 以下内容仅供参考. 使用古墓丽影暗影游戏,分别对这两个进行比较,得出的结论如下图(此笔记本散热很差,更改散热应该比下图结果好些): 首先看可以很 ...
- Linux命令应用大词典-第10章 Shell相关命令
10.1 commond:抑制正常的Shell函数查找 10.2 exec:使用执行命令替换当前的shell进程 10.3 bash:GNU的Bourne-Again Shell解释器 10.4 bu ...
- 题解 CF682C 【Alyona and the Tree】
简单搜索题,我们每找到一组不满足题目给出条件的点和边就将其整个子树删除,然后最终答案加上该子树的大小即可.注意,搜索的时候如果当前的边权和sum已经为负了,应该将其改为0(可以想想为什么) 注:题目翻 ...
- 【WXS】简要介绍说明
WXS(WeiXin Script)是小程序的一套脚本语言. WXS有二种写法: 1) 以<wxs>标签书写脚本: 语法: <wxs module="[String]&qu ...
- HDU - 6438(贪心+思维)
链接:HDU - 6438 题意:给出 n ,表示 n 天.给出 n 个数,a[i] 表示第 i 天,物品的价格是多少.每天可以选择买一个物品,或者卖一个已有物品,也可以什么都不做,问最后最大能赚多少 ...
- [转载]CENTOS 6.0 iptables 开放端口80 3306 22端口
原文地址:6.0 iptables 开放端口80 3306 22端口">CENTOS 6.0 iptables 开放端口80 3306 22端口作者:云淡风轻 #/sbin/iptab ...
- DeepLearning Intro - sigmoid and shallow NN
This is a series of Machine Learning summary note. I will combine the deep learning book with the de ...
- 一道java笔试题
输入一串用空格隔开的数字串,对于数字串的奇数位按升序排序,偶数位按降序排序. 示例输入: 4 6 2 3 6 7 8 1 处理过程: 奇数位:4 2 6 8 升序排序结果: 2 4 6 8 偶数位:6 ...
- Python中package的导入语法
在Python中,一个目录被称为一个package.import和from语法除了导入module文件之外,还可以导入package,语法如下: # import语法 import dir1.dir2 ...