【bzoj4889】: [Tjoi2017]不勤劳的图书管理员 分块-BIT
【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的更多相关文章
- 【BZOJ4889】[Tjoi2017]不勤劳的图书管理员 分块+树状数组
[BZOJ4889][Tjoi2017]不勤劳的图书管理员 题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让 ...
- [P3759][TJOI2017]不勤劳的图书管理员(分块+树状数组)
题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生 这两本书页数的和的厌烦度.现在有n本被打乱顺序的书 ...
- [bzoj4889] [Tjoi2017]不勤劳的图书管理员
Description 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被 ...
- bzoj4889: [Tjoi2017]不勤劳的图书管理员(树套树)
传送门 据说正解线段树套平衡树 然而网上参考(抄)了一个树状数组套动态开点线段树的 思路比较清楚,看代码应该就明白了 //minamoto #include<iostream> #incl ...
- 【BZOJ4889】不勤劳的图书管理员(树套树)
[BZOJ4889]不勤劳的图书管理员(树套树) 题面 又是权限题,烦死了 洛谷真好 题解 分开考虑每一次交换产生的贡献. 假设交换\((x,y)\) 检查\(x\)与\(y\)对于区间\([x+1, ...
- 洛谷P3759 - [TJOI2017]不勤劳的图书管理员
Portal Description 给出一个\(1..n(n\leq5\times10^4)\)的排列\(\{a_n\}\)和数列\(\{w_n\}(w_i\leq10^5)\),进行\(m(m\l ...
- 【loj2639】[Tjoi2017]不勤劳的图书管理员
#2639. 「TJOI2017」不勤劳的图书管理员 题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产 ...
- 【bzoj4889】[Tjoi2017]不勤劳的图书管理员 树状数组+分块+二分
题目描述(转自洛谷) 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被打 ...
- BZOJ4889 & 洛谷3759:[TJOI2017]不勤劳的图书管理员——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4889 https://www.luogu.org/problemnew/show/P3759 加里 ...
随机推荐
- 【BZOJ3998】弦论 【后缀自动机】
题意 给定一个长度为n的字符串,求他的第k小子串是什么. 分析 T=0的时候,这个题跟SPOJ-SUBLEX的做法一样,当T=1的时候,不同位置的子串算多个,那么初始化的时候d[u]=cnt[u],没 ...
- ubuntu配置ftp
0.sudo apt-get install vsftpd 1.vi /etc/vsftpd.conf 将里面的注释打开 2.sudo service vsftpd restart 3.端口号21
- DPDK收发包全景分析
前言:DPDK收发包是基础核心模块,从网卡收到包到驱动把包拷贝到系统内存中,再到系统对这块数据包的内存管理,由于在处理过程中实现了零拷贝,数据包从接收到发送始终只有一份,对这个报文的管理在前面的mem ...
- ApexSql Log 数据库操作的后悔药
ApexSQL Log破解版是一款功能强大的SQL数据恢复工具,支持SQL2005/2008/2012.很多时候我们存放在服务器中的SQL数据库会因黑客破坏或误操作造成数据库文件丢失的你问题,当数据库 ...
- Jedis连接Redis三种模式
这里说的三种工作模式是指: 1.单机模式 2.分片模式 3.集群模式(since 3.0) 说明图详见以下: 使用单机模式连接: private String addr="192.168.1 ...
- Windows7 64位 安装mysql
Windows上安装MySQL还是比较方便的,之前做过一个Windows10上面的安装方法,但是一个同学说自己的电脑是Windows7的,所以我写一个Windows7上的MySQL安装方法. MySQ ...
- es学习-索引管理
1.创建索引 http://localhost:9200/suoyinguanli211/ 参数: { "settings":{ "index":{ ,分片数 ...
- atom插件记录
├── Zen@0.16.4 写作的时候用,很给力 ├── atom-beautify@0.29.9 美化一切代码 ├── autocomplete-paths@1.0.2 路径自动提示 ├── au ...
- javascript总结系列49:javaScript教程:原型链不可变
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...
- (转)在ASP.NET MVC3 中利用Jsonp跨域访问
原文地址:http://www.cnblogs.com/skm-blog/p/3431999.html 在信息系统开发的时,根据相关业务逻辑难免会多系统之间互相登录.一般情况下我们需要在多系统之间使用 ...