【bzoj4889】: [Tjoi2017]不勤劳的图书管理员

题目大意:给定一个序列(n<=50000),每个数有一个编码ai(ai<=50000)和权值vi(vi<=100000),每次交换两个数的位置,交换m次(m<=50000)

求每次交换后的序列的杂乱度对1e9+7取模(对于每一对是逆序对的编码会产生两者权值和的杂乱度)。

感觉正解是什么奇怪的树套树?蒟蒻只会分块水题。。

先用BIT求一遍初始状态的杂乱度。。(不要问我为什么一开始是BIT。。因为打暴力正好用到就懒得改了。。感觉直接分块也行)

然后开始分块。。分块完对每个块内排序,然后求出排序完之后的权值前缀和。

考虑每次交换操作,若原有序列是 A B C D E,交换B D

那么其实改变的杂乱度只跟B->D的序列有关,跟A E无关

仔细讨论一下就是

当aB<aD

改变的杂乱度会是

C段里所有编号比aB大的权值和 + C段里所有编号比aB大的个数*vB  -  C段里所有编号比aB小的权值和 - C段里所有编号比aB小的个数*vB

C段里所有编号比aD小的权值和 + C段里所有编号比aD小的个数*vD  -  C段里所有编号比aD大的权值和 - C段里所有编号比aD大的个数*vD

当aB>aD

贡献符号相反。

如果B!=D 还会加上 vB+vD的贡献

按照这种讨论在分块里各种暴力瞎搞二分就好了。。

然后最后再把BD所在的块暴力重建就做完了。。

 /* http://www.cnblogs.com/karl07/ */
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std; #define ll long long
#define lowbit(x) (x&-x)
const int N=1e5+;
const int P=1e9+;
const int MX=1e5;
int n,m,cnt;
int pos[N],st[N];
ll bit[N],bb[N];
ll lst=;
struct data{
int x,y;
}a[N],b[N]; bool oper(data a,data b){
return a.x<b.x;
} void modify(int i){
for (int j=st[i];j<st[i+];j++){
b[j].x=a[j].x;
b[j].y=a[j].y;
}
sort(b+st[i],b+st[i+],oper);
for (int j=st[i]+;j<st[i+];j++){
b[j].y=(b[j].y+b[j-].y)%P;
}
} int find(int l,int r,int x){
int mid=(l+r)/,ans=l-;
while (l<=r){
mid=(l+r)/;
if (b[mid].x<x){
ans=mid;
l=mid+;
}else{
r=mid-;
}
}
return ans;
} ll query(int x,int mn,int mx,int ny,int xy){
int p1=find(st[x],st[x+]-,mx),p2=find(st[x],st[x+]-,mn);
ll ans=;
ans+=(b[p1].y)*(p1>=st[x])+(p1-st[x]+)*xy%P;
ans+=b[st[x+]-].y-b[p2].y*(p2>=st[x])+ny*(st[x+]--p2)%P;
swap(p1,p2);
ans-=(b[p1].y)*(p1>=st[x])+(p1-st[x]+)*ny%P;
ans-=b[st[x+]-].y-b[p2].y*(p2>=st[x])+xy*(st[x+]--p2)%P;
return ans%P;
} void build(){
int sz=sqrt(n)/;
for (int i=;i<=n;i++){
if (sz== || i%sz==){
st[++cnt]=i;
}
pos[i]=cnt;
}
st[cnt+]=n+;
for (int i=;i<=cnt;i++){
modify(i);
}
} void Modify(int x,int y){
while (x<=MX){
bit[x]+=y;
bb[x]++;
bit[x]%=P;
x+=lowbit(x);
}
} ll Query(int x,int y){
ll ans=,a2=;
while (x){
ans+=bit[x];
a2+=bb[x];
ans%=P;
x-=lowbit(x);
}
ans+=a2*y%P;
return ans%P;
} int main(){
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++){
scanf("%d%d",&a[i].x,&a[i].y);
}
for (int j=;j<=n;j++){
lst+=Query(MX,a[j].y)-Query(a[j].x,a[j].y);
lst%=P;
Modify(a[j].x,a[j].y);
}
build();
for (int i=;i<=m;i++){
int x,y,x1,y1,px,py,mn,mx,ny,xy;
ll ans=;
scanf("%d%d",&x1,&y1);
x=min(x1,y1);
y=max(x1,y1);
px=pos[x],py=pos[y];
if (a[x].x<a[y].x) mn=a[x].x,ny=a[x].y,mx=a[y].x,xy=a[y].y;
else mx=a[x].x,xy=a[x].y,mn=a[y].x,ny=a[y].y;
if (px!=py){
for (int i=x+;i<st[px+];i++){
ans+= (a[i].x>mn)*(a[i].y+ny);
ans+= (a[i].x<mx)*(a[i].y+xy); ans-= (a[i].x<mn)*(a[i].y+ny);
ans-= (a[i].x>mx)*(a[i].y+xy);
ans%=P;
}
for (int i=st[py];i<y;i++){
ans+= (a[i].x>mn)*(a[i].y+ny);
ans+= (a[i].x<mx)*(a[i].y+xy); ans-= (a[i].x<mn)*(a[i].y+ny);
ans-= (a[i].x>mx)*(a[i].y+xy);
ans%=P; }
for (int i=px+;i<=py-;i++){
ans+= query(i,mn,mx,ny,xy);
ans%=P;
}
}else{
for (int i=x+;i<y;i++){
ans+= (a[i].x>mn)*(a[i].y+ny);
ans+= (a[i].x<mx)*(a[i].y+xy); ans-= (a[i].x<mn)*(a[i].y+ny);
ans-= (a[i].x>mx)*(a[i].y+xy);
}
ans%=P; }
if (x!=y) ans+=a[x].y+a[y].y;
ans%=P;
if (a[x].x>a[y].x) ans=(-ans+P)%P;
printf("%lld\n",lst=(lst+ans+P)%P);
swap(a[x],a[y]);
modify(pos[x]);
modify(pos[y]);
}
return ;
}

另外当块的大小取sqrt(n)/2的时候跑的飞快。。

40s就跑出来了。。竟然有rank5(2017.5.27)。。而且空间也很小有没有。。

【bzoj4889】: [Tjoi2017]不勤劳的图书管理员 分块-BIT的更多相关文章

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

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

  2. [P3759][TJOI2017]不勤劳的图书管理员(分块+树状数组)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 用django框架开发一个B2C购物网站的基本流程和用到的知识点总结1

    开发流程 开发模式采用前后端分离模式,作为后端开发人员我们只关注后端业务逻辑开发: 省略项目框架搭建文件的配置部分.... 一:用户部分 在项目开发中我们要用到用户模型类User,Django认证系统 ...

  2. 使用火狐浏览器访问双向认证的k8s api

    首先 不能在火狐里对要访问的网址添加例外 打开 选项->高级->查看证书->证书机构->导入.先择服务端ca.crt后根据提示导入证书 生成p12文件 openssl pkcs ...

  3. Linux实战教学笔记32:企业级Memcached服务应用实践

    一, Memcached介绍 1.1 Memcached与常见同类软件对比 (1)Memcached是什么? Memcached是一个开源的,支持高性能,高并发的分布式内存缓存系统,由C语言编写,总共 ...

  4. Apache Hive (三)Hive元数据信息对应MySQL数据库表

    转自:https://www.cnblogs.com/qingyunzong/p/8710356.html 概述 Hive 的元数据信息通常存储在关系型数据库中,常用MySQL数据库作为元数据库管理. ...

  5. shell if,case,for,while语法

    #shell if的语法 if [空格 xxx 空格] then echo xxxxx exit 1/2/3/4/.... 0表示正确. elif [空格 xxx 空格] then echo xxxx ...

  6. Docker学习记录常用命令

    1. docker ps  -a 查看运行中的容器 2. docker images 查看docker镜像 3. docker rm id(容器id)  删除容器(容器id可以通过docker ps查 ...

  7. 转载 二十篇java技术热文

    转自微信公众号:java知音 1,详解java类的生命周期 2,Java反射最佳实践 3,Spring的IOC原理 4,Java并发编程:volatile关键字解析 5,Java Thread 总结 ...

  8. [Fiddler]如何让Fiddler可以抓取https的请求

    Fiddler通过在本机开启了一个http的代理服务器来进行http请求和响应转发,默认情况下,并不能抓取https的请求.下面小编就来介绍下,如何用fiddler来抓取https的请求. 1.打开F ...

  9. c#反射优化 表达式树

    using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; us ...

  10. C#变量初始化

    在C#中声明变量使用下述语法: datatype identifier;, 例如: int i; 该语句声明int变量i.编译器不允许在表达式中使用这个变量,除非用一个值初始化了改变量.如果你不需要使 ...