【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. lock free queues

    无锁队列,下面链接是源码,包含4种队列:单生产者单消费者/多生产者多消费者,队列定长/不定长.元素建议为简单数据类型,复杂类型都采用指针形式. queues-master.zip 源码来源:https ...

  2. 145. Binary Tree Postorder Traversal (Stack, Tree)

    Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary ...

  3. NavigationController.viewControllers

      NSMutableArray *viewControllersArray = [NSMutableArray new];    // 获取当前控制器数组    for (CardLoanBaseT ...

  4. windows 查看端口被占用进程

    查看占用63243是谁 C:\Users\Administrator>netstat -aon|findstr "63243" TCP 172.27.33.11:63243 ...

  5. Linux cloc

    一.简介 cloc是一个基于perl的.十分好用的代码统计工具,它所支持的语言还算十分丰富.不过,还是有很多用的较少的语言是不支持的.   二.安装配置 1)官网安装教程 http://cloc.so ...

  6. code1796 社交网络

    输入描述 Input Description 输入文件中第一行有两个整数,n 和 m,表示社交网络中结点和无向边的数 目.在无向图中,我们将所有结点从 1 到 n 进行编号. 接下来 m 行,每行用三 ...

  7. tp5 $this/Db

  8. TIMER_PWM_CAPTURE

  9. [随笔]CENTOS7更换YUM源为163源(记录一下以防忘记)

    2016年2月16日,最新163源变更后的更新方法: 访问地址为:http://mirrors.163.com/.help/centos.html 首先备份源: mv /etc/yum.repos.d ...

  10. .NET分布式事务处理(转)

    出处:http://www.cnblogs.com/youring2/archive/2011/06/12/MSDTC.html 在进行数据持久化的时候,我们会经常用到事务处理.一般情况下,ADO.N ...