【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后输出

输入输出样例

输入样例#1:

5 5
1 1
2 2
3 3
4 4
5 5
1 5
1 5
2 4
5 3
1 3

输出样例#1:

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

转载于:https://www.cnblogs.com/CQzhangyu/p/7128300.html

【BZOJ4889】[Tjoi2017]不勤劳的图书管理员 分块+树状数组相关推荐

  1. [BZOJ4889][洛谷P3759][TJOI2017]不勤劳的图书管理员 分块+树状数组

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

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

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

  3. 【loj2639】[Tjoi2017]不勤劳的图书管理员

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

  4. 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

    题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见-- 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...

  5. 【XSY2111】Chef and Churus 分块 树状数组

    题目描述 有一个长度为\(n\)的数组\(A\)和\(n\)个区间\([l_i,r_i]\),有\(q\)次操作: \(1~x~y\):把\(a_x\)改成\(y\) \(2~x~y\):求第\(l\ ...

  6. 牛客小白月赛12 F 华华开始学信息学 (分块+树状数组)

    链接:https://ac.nowcoder.com/acm/contest/392/F 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 32768K,其他语言65536 ...

  7. bzoj 4765: 普通计算姬(分块+树状数组)

    4765: 普通计算姬 Time Limit: 30 Sec  Memory Limit: 256 MB Submit: 1481  Solved: 318 [Submit][Status][Disc ...

  8. [队内测试Day10.12]贪心+状压+分块+树状数组

    T1 codevs2169零用钱 正解贪心. 在使用钞票最少前提下保证浪费的钱数最少 保证第一条,在还没达到规定钱数时尽可能使用大面值钞票 保证第二条,在现有钞票不满足要求前提下,尽量选面值小的放 综 ...

  9. 周末狂欢赛2(冒泡排序,概率充电器,不勤劳的图书管理员)

    狂欢2 T1:冒泡排序 题目 题解 CODE T2:概率充电器 题目 题解 CODE T3:不勤劳的图书管理员 题目 题解 CODE 我不这么认为.... T1:冒泡排序 题目 下面是一段实现冒泡排序 ...

最新文章

  1. 动态规划面试常考:最短路径和
  2. python__基础 : 类的__init__,__str__,__del__方法
  3. Jsp传值方式(乱码问题的解决)
  4. django使用mysql原始语句,Django中使用mysql数据库并使用原生sql语句操作
  5. 洛谷P1938 找工就业
  6. 面对数据缺失,如何选择合适的机器学习模型?
  7. 以下关于python自动化运维错误的是_建设银行Python自动化运维考试
  8. 计算机信息学中比较大小的代码,信息学奥赛计算机基础知识.doc
  9. MATLAB中的imagesc
  10. 新浪igame连连看游戏截图
  11. 计算机文化基础的重点,计算机文化基础重点知识(1)
  12. 单片机大学生实习感悟体验
  13. CodeForces 1418C Mortal Kombat Tower
  14. netcat基本使用方法总结
  15. 07-Web storage
  16. Redis各版本描述
  17. 全球及中国暗箱针孔相机行业需求潜力与销售前景态势分析报告2022版
  18. Python实现布林带策略
  19. 炸分王的省选2021(A)游记
  20. Dxf 3d模型素材推荐

热门文章

  1. 《网安学习之道》预告
  2. “囚徒”李一男回归华为真相揭密
  3. SAP.CATT 批处理/批量操作的基本应用
  4. 极品,git简介,安装,方法
  5. HTTP返回soapxml解析为实体类
  6. 冒泡排序 | 快速排序 | 线性查找 | 二分查找等
  7. ElasticFusion离线数据集运行结果再现问题总结
  8. JVM 2eden survivor分配问题)
  9. BUUCTF 逆向工程(reverse)之findit
  10. 用事实说话!AJAX应用程序开发七宗罪