[P3759][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后输出
输入输出样例
说明
对于20%的数据,1 ≤ ai; xj; yj ≤ n ≤ 5000, m ≤ 5000, vi ≤ 10^5
对于100%的数据,1 ≤ ai; xj; yj ≤ n ≤ 50000, m ≤ 50000, vi ≤ 10^5
不想写或者不会写数据结构的用分块就好,然后有两种写法,一种是对每一块排序,一种是对每块维护一个树状数组。
这样分L和R在同一块,L和R所在的两个不完整的块,L和R跨过的完整的块三种情况讨论即可。
注意!!这题前两种情况一定不能暴力重建块!暴力重建的用时是1200+s,如果只更新变化的部分就只要80+s。
还有一个问题,因为整块标记的复杂度是$O(\frac{n}{S} \log n)$的(其中S是块的大小),所以S设为$\sqrt{n \log n}$的速度是设为$\sqrt{n}$的两倍。
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long ll;
#define rep(i,l,r) for (register int i=l; i<=r; i++)
using namespace std; const ll N=,md=;
int n,m,mx,L,R,B,a[N],v[N],sz[N],bl[N],cnt,sum[N],d[],c[][N],c1[][N],ans; void add(int c[],int x,int k){ for (; x<=n; x+=x&-x) c[x]=(c[x]+k)%md; }
int que(int c[],int x){ ll res=; for (; x; x-=x&-x) res=(res+c[x])%md; return res; }
void add1(int c1[],int x,int k){ for (; x<=n; x+=x&-x) c1[x]=(c1[x]+k)%md; }
int que1(int c1[],int x){ ll res=; for (; x; x-=x&-x) res=(res+c1[x])%md; return res; }
int get(int x){ return x>= ? x : x+md; } void cal(int x,int y,int z){
if (a[x]<a[z]) ans=(ans+v[x]+v[z])%md; else ans=(ans-v[x]-v[z]+md+md)%md;
if (a[y]<a[z]) ans=(ans+md+md-v[y]-v[z])%md; else ans=(ans+v[y]+v[z])%md;
} void work(int L,int R){
if (L==R) return;
if (bl[L]==bl[R]){
rep(i,L+,R-) cal(L,R,i); swap(a[L],a[R]); swap(v[L],v[R]);
}else{
rep(i,L+,(bl[L]-)*B+sz[bl[L]]) cal(L,R,i);
rep(i,(bl[R]-)*B+,R-) cal(L,R,i);
swap(a[L],a[R]); swap(v[L],v[R]);
sum[bl[L]]=(sum[bl[L]]+md-v[R]+v[L])%md; sum[bl[R]]=(sum[bl[R]]+md-v[L]+v[R])%md;
add(c[bl[R]],a[L],-v[L]); add(c[bl[L]],a[R],-v[R]); add1(c1[bl[R]],a[L],-); add1(c1[bl[L]],a[R],-);
add(c[bl[L]],a[L],v[L]); add(c[bl[R]],a[R],v[R]); add1(c1[bl[L]],a[L],); add1(c1[bl[R]],a[R],);
rep(i,bl[L]+,bl[R]-){
ans=get((1ll*ans-(que(c[i],a[R]-)+1ll*que1(c1[i],a[R]-)*v[R])%md));
ans=get((1ll*ans+(que(c[i],a[L]-)+1ll*que1(c1[i],a[L]-)*v[L]))%md);
ans=get((1ll*ans-(sum[i]-que(c[i],a[L])+1ll*(sz[i]-que1(c1[i],a[L]))*v[L]))%md);
ans=get((1ll*ans+(sum[i]-que(c[i],a[R])+1ll*(sz[i]-que1(c1[i],a[R]))*v[R]))%md);
}
}
if (a[R]<a[L]) ans=(1ll*ans+v[L]+v[R])%md; else ans=get((1ll*ans-(v[L]+v[R]))%md);
} int main(){
freopen("book.in","r",stdin);
freopen("book.out","w",stdout);
scanf("%d%d",&n,&m); B=(int)sqrt(n*);
rep(i,,n) scanf("%d%d",&a[i],&v[i]);
rep(i,,n) bl[i]=(i-)/B+; mx=(n-)/B+;
rep(i,,mx-) sz[i]=B; sz[mx]=n-(mx-)*B;
rep(i,,n) add(c[bl[i]],a[i],v[i]),add1(c1[bl[i]],a[i],),sum[bl[i]]=(sum[bl[i]]+v[i])%md;
rep(i,,n){
ans=get((1ll*ans+(i--1ll*que1(c1[],a[i]-))*v[i]+cnt-que(c[],a[i]-))%md);
add(c[],a[i],v[i]); add1(c1[],a[i],); cnt=(cnt+v[i])%md;
}
rep(i,,m) scanf("%d%d",&L,&R),work(min(L,R),max(L,R)),printf("%d\n",ans);
return ;
}
[P3759][TJOI2017]不勤劳的图书管理员(分块+树状数组)的更多相关文章
- 【BZOJ4889】[Tjoi2017]不勤劳的图书管理员 分块+树状数组
[BZOJ4889][Tjoi2017]不勤劳的图书管理员 题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让 ...
- 洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】
题目链接 洛谷P3759 题解 树状数组套主席树板题 #include<algorithm> #include<iostream> #include<cstring> ...
- 【bzoj4889】: [Tjoi2017]不勤劳的图书管理员 分块-BIT
[bzoj4889]: [Tjoi2017]不勤劳的图书管理员 题目大意:给定一个序列(n<=50000),每个数有一个编码ai(ai<=50000)和权值vi(vi<=100000 ...
- 洛谷P3759 - [TJOI2017]不勤劳的图书管理员
Portal Description 给出一个\(1..n(n\leq5\times10^4)\)的排列\(\{a_n\}\)和数列\(\{w_n\}(w_i\leq10^5)\),进行\(m(m\l ...
- LUOGU P3759 [TJOI2017]不勤劳的图书管理员(树套树)
传送门 解题思路 和以前做过的一道题有点像,就是区间逆序对之类的问题,用的是\(BIT\)套权值线段树,交换时讨论一下计算答案..跑的不如暴力快.. 代码 #include<iostream&g ...
- P3759 [TJOI2017]不勤劳的图书管理员 [树套树]
树套树是什么啊我不知道/dk 我只知道卡常数w // by Isaunoya #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC o ...
- 【洛谷3759】[TJOI2017] 不勤劳的图书管理员(树套树)
点此看题面 大致题意: 给定一个序列,每个元素有两个属性\(a_i\)和\(v_i\),每次操作改变两个元素的位置,求每次操作后\(\sum{v_i+v_j}[i<j,a_i>a_j]\) ...
- bzoj4889: [Tjoi2017]不勤劳的图书管理员(树套树)
传送门 据说正解线段树套平衡树 然而网上参考(抄)了一个树状数组套动态开点线段树的 思路比较清楚,看代码应该就明白了 //minamoto #include<iostream> #incl ...
- 【loj2639】[Tjoi2017]不勤劳的图书管理员
#2639. 「TJOI2017」不勤劳的图书管理员 题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产 ...
随机推荐
- Vue 脱坑记
问题汇总 Q:安装超时(install timeout) 方案有这么些: cnpm : 国内对npm的镜像版本 /* cnpm website: https://npm.taobao.org/ */ ...
- pycharts实现可视化
https://blog.csdn.net/u012535605/article/details/80677791http://pyecharts.org/#/zh-cn/prepare (中文官网 ...
- Ubuntu 17.10 用 apt 搭建 lamp 环境、安装 phpmyadmin、redis 服务+扩展、mysql 扩展、开启错误提示、配置虚拟主机
2018-02-24 13:50:30 更新: 个人喜欢相对原生又不太麻烦,所以用 apt 构建环境.不过,最近使用到现在记得出现过了 3 次 apache 或 mysql 服务器无法启动或无法连接的 ...
- 516.Longest Palindromic subsequence---dp
题目链接:https://leetcode.com/problems/longest-palindromic-subsequence/description/ 题目大意:找出最长回文子序列(不连续), ...
- (五)Spring 对事务的支持
第一节:事务简介 满足一下四个条件: 第一:原子性: 第二:一致性: 第三:隔离性: 第四:持久性: ------------------------------------------------- ...
- hive学习(六) 参数和动态分区
1.hive 参数.变量 1.1hive的命名空间: hive当中的参数.变量,都是以命名空间开头
- Linux 用户篇——用户管理命令之id、whoami、su、chage
一.浅谈id.whoami.su.chage 本篇是续写上一篇<Linux 用户篇——用户管理命令之useradd.passwd.userdel.usermod>. (1)id命令 命令格 ...
- bug优先级定义
优先级定义如下: <版本前期阶段>(功能刚提测): [P0—紧急]:完全不能满足产品要求,基本功能明显未实现或完全不可用,阻塞测试流程与进度(核心功能流程) 1.功能未实现 .功能缺失 2 ...
- 使用 Python 的 sounddevice 包录制系统声音
博客中的文章均为meelo原创,请务必以链接形式注明本文地址 sounddevice是一个与Numpy兼容的录音以及播放声音的包. 安装sounddevice包 直接通过pip就能安装. pip in ...
- SGU 217. Two Cylinders
题意:给空间内两根圆柱,求轴线垂直相交时公共部分的体积. 暴力积分即可. ID: Date'n'Time: Name: Task: .Ext: Status: Time: Memory: 158937 ...