题目描述

加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员。他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生 这两本书页数的和的厌烦度。现在有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

不想写或者不会写数据结构的用分块就好,然后有两种写法,一种是对每一块排序,一种是对每块维护一个树状数组。

这样分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]不勤劳的图书管理员(分块+树状数组)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

    树套树是什么啊我不知道/dk 我只知道卡常数w // by Isaunoya #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC o ...

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

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

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

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

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

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

随机推荐

  1. oozie与hive的简单案例

    1.把oozie中自带的hive案例拷贝到 测试目录 /opt/cdh-5.3.6/oozie-4.0.0-cdh5.3.6/oozie-apps下 2. 编辑 job.properties # # ...

  2. scandir函数的研究【笔记】

    以下是本人的学习笔记,代码并非原创,均摘自官方源码,贴出来仅供学习记录用 scandir 的使用要注意内存泄漏的问题 scandir函数实现: vi ./uClibc-0.9.33.2/libc/mi ...

  3. selenium只打开一个浏览器窗口

    from selenium.webdriver import Remote from selenium.webdriver.chrome import options from selenium.co ...

  4. Machine Learning系列--判别式模型与生成式模型

    监督学习的任务就是学习一个模型,应用这一模型,对给定的输入预测相应的输出.这个模型的一般形式为决策函数:$$ Y=f(X) $$或者条件概率分布:$$ P(Y|X) $$监督学习方法又可以分为生成方法 ...

  5. 微信开发,调用js-SDK接口

    微信开发,调用js-SDK接口<!DOCTYPE html><html><head lang="en"> <meta charset=&q ...

  6. postman中 form-data、x-www-form-urlencoded、raw、binary的区别 && 下载文件

    1.form-data:  就是http请求中的multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开.既可以上传键值对,也可以上传文件.当上传的字段是文件 ...

  7. 转:PHP环境搭建 - Linux

    本文PHP环境采用,nginx + PHP7 + mysql 5.6 一.安装mysql 5.6 参见:http://www.cnblogs.com/rslai/p/7853465.html 二.Ng ...

  8. Gradient-Based Learning Applied to Document Recognition 部分阅读

    卷积网络        卷积网络用三种结构来确保移位.尺度和旋转不变:局部感知野.权值共享和时间或空间降采样.典型的leNet-5如下图所示: C1中每个特征图的每个单元和输入的25个点相连,这个5* ...

  9. virtualenv python的虚拟环境

    官网:https://virtualenv.pypa.io/en/stable/userguide/ virtualenv通过创建独立Python开发环境的工具, 来解决依赖.版本问题 基本使用: d ...

  10. Eclipse中用两个控制台测试网络通信程序

    1.启动发送端和接收端程序,这时在控制台可以看到两个程序在运行,如下图. 2.这种情况下只有一个控制台窗口,不便于测试程序,于是新建一个控制台窗口,如下图. 3.这时可以发现已经有了两个控制台窗口了, ...