4889: [Tjoi2017]不勤劳的图书管理员 树套树
国际惯例的题面(Bzoj没有,洛谷找的):
动态加权逆序对,一眼树套树。
256MB内存,5e4范围,不虚不虚。
首先把交换改成两个插入和两个删除。
考虑插入和删除的贡献,就是统计前面比这个值大的数的数值和,数量和,后面比这个值小的数的数值和,数量和。然后特判一下当前两个值构成逆序对的情况即可(因为这种情况会被计算两遍)。
考虑树状数组套动态开点线段树维护这个东西,线段树只需要单点修改区间求和即可,十分简单。
然而数组开不下啊......理论上我们数组范围要开到2e7左右,然而并跑不满,开到1.4e7就足以AC啦。
(但是跑得奇慢无比,怕不是人傻自带大常数)
代码(话说两个log差不多是根号,我这是两个log还有4倍的常数,大概已经比根号慢了):
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long int lli;
const int maxn=5e4+1e2,maxe=1.4e7+1e2;
const int mod=1e9+; int in[maxn],seq[maxn],n; struct SegmentTree {
int lson[maxe],rson[maxe],sum[maxe],siz[maxe],cnt;
inline void insert(int &pos,int l,int r,const int &tar,const int &x,const int &d) {
if( !pos ) pos = ++cnt;
sum[pos] = ( sum[pos] + x ) % mod , siz[pos] += d;
if( l == r ) return;
const int mid = ( l + r ) >> ;
if( tar <= mid ) insert(lson[pos],l,mid,tar,x,d);
else insert(rson[pos],mid+,r,tar,x,d);
}
inline int querysum(int pos,int l,int r,const int &ll,const int &rr) {
if( !pos || ( ll <= l && r <= rr ) ) return sum[pos];
const int mid = ( l + r ) >> ;
if( rr <= mid ) return querysum(lson[pos],l,mid,ll,rr);
else if( ll > mid ) return querysum(rson[pos],mid+,r,ll,rr);
return ( querysum(lson[pos],l,mid,ll,rr) + querysum(rson[pos],mid+,r,ll,rr) ) % mod;
}
inline int querysiz(int pos,int l,int r,const int &ll,const int &rr) {
if( !pos || ( ll <= l && r <= rr ) ) return siz[pos];
const int mid = ( l + r ) >> ;
if( rr <= mid ) return querysiz(lson[pos],l,mid,ll,rr);
else if( ll > mid ) return querysiz(rson[pos],mid+,r,ll,rr);
return ( querysiz(lson[pos],l,mid,ll,rr) + querysiz(rson[pos],mid+,r,ll,rr) ) % mod;
}
}sgt; struct BinaryIndexTree {
int root[maxn],id;
#define lowbit(x) (x&-x)
inline void update(int x,const int &y,const int &val,const int &vs) {
while( x <= n ) sgt.insert(root[x],,n,y,val,vs) , x += lowbit(x);
}
inline int querysum(int x,const int &ll,const int &rr) {
int ret = ;
while(x) ret = ( ret + sgt.querysum(root[x],,n,ll,rr) ) % mod , x -= lowbit(x);
return ret;
}
inline int querysiz(int x,const int &ll,const int &rr) {
int ret = ;
while(x) ret = ( ret + sgt.querysiz(root[x],,n,ll,rr) ) % mod , x -= lowbit(x);
return ret;
}
}bit; inline int segsum(const int &l,const int &r,const int &ll,const int &rr) {
return ( bit.querysum(r,ll,rr) - bit.querysum(l-,ll,rr) + mod ) % mod;
}
inline int segsiz(const int &l,const int &r,const int &ll,const int &rr) {
return ( bit.querysiz(r,ll,rr) - bit.querysiz(l-,ll,rr) + mod ) % mod;
} int main() {
static int m;
static lli now;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",seq+i) , scanf("%d",in+seq[i]);
for(int i=;i<=n;i++) {
now = ( now + bit.querysum(i,seq[i]+,n) ) % mod , now = ( now + (lli) bit.querysiz(i,seq[i]+,n) * in[seq[i]] % mod ) % mod;
bit.update(i,seq[i],in[seq[i]],);
}
for(int i=,a,b;i<=m;i++) {
scanf("%d%d",&a,&b);
if( a > b ) std::swap(a,b);
if( a == b ) {
printf("%lld\n",now);
continue;
}
now -= segsum(,a-,seq[a]+,n) + segsum(a+,n,,seq[a]-) , now -= (lli) in[seq[a]] * ( segsiz(,a-,seq[a]+,n) + segsiz(a+,n,,seq[a]-) ) % mod , now = ( now % mod + mod ) % mod;
now -= segsum(,b-,seq[b]+,n) + segsum(b+,n,,seq[b]-) , now -= (lli) in[seq[b]] * ( segsiz(,b-,seq[b]+,n) + segsiz(b+,n,,seq[b]-) ) % mod , now = ( now % mod + mod ) % mod;
bit.update(b,seq[b],mod-in[seq[b]],-) , bit.update(a,seq[a],mod-in[seq[a]],-);
if( seq[a] > seq[b] ) now = ( now + in[seq[a]] + in[seq[b]] ) % mod; // it have been subed two times .
std::swap(seq[a],seq[b]);
bit.update(a,seq[a],in[seq[a]],) , bit.update(b,seq[b],in[seq[b]],);
now += segsum(,a-,seq[a]+,n) + segsum(a+,n,,seq[a]-) , now += (lli) in[seq[a]] * ( segsiz(,a-,seq[a]+,n) + segsiz(a+,n,,seq[a]-) ) % mod , now = ( now % mod + mod ) % mod;
now += segsum(,b-,seq[b]+,n) + segsum(b+,n,,seq[b]-) , now += (lli) in[seq[b]] * ( segsiz(,b-,seq[b]+,n) + segsiz(b+,n,,seq[b]-) ) % mod , now = ( now % mod + mod ) % mod;
if( seq[a] > seq[b] ) now = ( now - in[seq[a]] - in[seq[b]] + mod ) % mod; // it have been added two times .
printf("%lld\n",now);
}
return ;
}
(另外我为什么又在刷水题了!)
空に舞う雪はまるで白い花びら ひらひら 風に吹かれて散よ
在茫茫天空飞舞着 好似纯白花朵的雪花 迎风飘洒
Ah…染めあげて 消えて無くなるのなら この寂しさも一緒に溶けてゆけ
啊…全都染上純白 如果那些色彩渐渐消失不见的话 那也让这寂寞溶于一起消失吧
約束を交わす事もなくて 不安が募るばかり
想到相互所约定的那些事情 就会感到越来越不安
ありふれた言葉でもいい 今はただ信じさせて
就算是平常无奇的言语也好 这是如今唯一让我相信的
この慣れた道も 二人なら幸せ
这条熟悉的道路上 是我们两人的话 那我会感到幸福的
届かぬ想いを伝えられたら 未来変わるのかな?
那些无法传达的思念 若是能够传达给你 未来会不会就此发生改变
4889: [Tjoi2017]不勤劳的图书管理员 树套树的更多相关文章
- [TJOI2017]不勤劳的图书管理员(分块+树状数组)
有一个数组开大会MLE开小会RE的做法:就是树套树,即树状数组套主席树,这种方法比较暴力,然而很遗憾它不能通过,因为其时空复杂度均为O(nlog2n). 想到一种不怎么耗内存,以时间换空间,分块!单次 ...
- 【BZOJ4889】[Tjoi2017]不勤劳的图书管理员 分块+树状数组
[BZOJ4889][Tjoi2017]不勤劳的图书管理员 题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让 ...
- 【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 ...
- 【洛谷3759】[TJOI2017] 不勤劳的图书管理员(树套树)
点此看题面 大致题意: 给定一个序列,每个元素有两个属性\(a_i\)和\(v_i\),每次操作改变两个元素的位置,求每次操作后\(\sum{v_i+v_j}[i<j,a_i>a_j]\) ...
- P3759 [TJOI2017]不勤劳的图书管理员 [树套树]
树套树是什么啊我不知道/dk 我只知道卡常数w // by Isaunoya #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC o ...
- 【loj2639】[Tjoi2017]不勤劳的图书管理员
#2639. 「TJOI2017」不勤劳的图书管理员 题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产 ...
- [TJOI2017] 不勤劳的图书管理员
题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被打乱顺序的书, ...
- Luogu 3759 [TJOI2017]不勤劳的图书管理员
再也不作死写FhqTreap作内层树了,卡的不如暴力呜呜呜…… 题意翻译:给一个序列,每个下标包含两个属性$a$和$v$,求第一个属性与下标形成的所有逆序对的第二个属性和,给出$m$个交换两个下标的操 ...
随机推荐
- [转]SPI通信原理简介
[转自]http://www.cnblogs.com/deng-tao/p/6004280.html 1.前言 SPI是串行外设接口(Serial Peripheral Interface)的缩写.是 ...
- Linux系统无线网卡的安装【转】
转自:http://www.linuxidc.com/Linux/2013-03/81473.htm 现在的很多的可移动无线网卡都是usb接口的,把这种网卡应用到windows操作系统上是很容易就能起 ...
- 升级tomcat需要更改哪些配置?
1.上传Tomcatapache-tomcat-7.0.84.zip将38服务器上的Tomcat传到107服务器指定目录:scp /data/apache-tomcat-7.0.84.zip jsdx ...
- html的结构-厂子型的布局
上图所示的布局设计是很常见的.这个该怎么做呢? 技术需求:header 要固定住在顶部,不随鼠标滚动而向上移动:左边的div的有一定的宽度,但是要贴浏览器的底部(屏幕顶部):右边的dv要占据右边的全屏 ...
- centos6.5环境通达OA数据库mysql5.0.67升级至mysql5.5.48方案
centos6.5环境通达OA数据库mysql5.0.67升级至mysql5.5.42方案 整体方案: 环境准备,在备用服务器安装mysql5.5数据库 1.停用生产环境的应用访问 直接修改web的访 ...
- 如何在DOS窗口复制和粘贴命令
在键盘上按下windows+R键,打开运行窗口. 在“打开”处输入cmd,并按下enter键,打开DOS窗口. 把鼠标移动到DOS窗口标题处,单击鼠标右键,选择属性. 把编辑选项处的“快速编辑模式”勾 ...
- Java连接oracle数据库的两种常用方法
1. 使用thin连接 由于thin驱动都是纯Java代码,并且使用TCP/IP技术通过java的Socket连接上Oracle数据库,所以thin驱动是与平台无关的,你无需安装Oracle客户端,只 ...
- VeeValidate配置中文的两种方法
使用VeeValidate时遇到的问题,下面是我找到的一些解决办法: VeeValidate一直报错早不到addlocale方法 解决办法:1.卸载掉当前版本,重新安装低版本如2.0.0-rc.25 ...
- php-fpm 配置文件检测
用过 Nginx 的兄弟都知道,修改 Nginx 配置文件之后,可以使用 nginx -t 来检测配置文件是否有语法错误. 今天配置 opcache 的时候,发现 php-fpm 也可以检测 php- ...
- php协程
多任务 (并行和并发) 在讲协程之前,先谈谈多进程.多线程.并行和并发. 对于单核处理器,多进程实现多任务的原理是让操作系统给一个任务每次分配一定的 CPU 时间片,然后中断.让下一个任务执行一定的时 ...