LUOGU P3759 [TJOI2017]不勤劳的图书管理员(树套树)
解题思路
和以前做过的一道题有点像,就是区间逆序对之类的问题,用的是\(BIT\)套权值线段树,交换时讨论一下计算答案。。跑的不如暴力快。。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=50005;
const int M=N*200;
const int MOD=1e9+7;
typedef long long LL;
inline int rd(){
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return f?x:-x;
}
int n,m,a[N],val[N],tot,rt[N];
LL ans;
struct Segment_Tree{
int sum[M],num[M],ls[M],rs[M];
void update_num(int &x,int l,int r,int pos,int k){
if(!x) x=++tot; num[x]+=k; num[x]%=MOD;
if(l==r) return; int mid=(l+r)>>1;
if(pos<=mid) update_num(ls[x],l,mid,pos,k);
else update_num(rs[x],mid+1,r,pos,k);
}
void update_sum(int &x,int l,int r,int pos,int k){
if(!x) x=++tot; (sum[x]+=k)%=MOD;
if(l==r) return; int mid=(l+r)>>1;
if(pos<=mid) update_sum(ls[x],l,mid,pos,k);
else update_sum(rs[x],mid+1,r,pos,k);
}
int query_sum(int x,int l,int r,int L,int R){
if(!x) return 0; if(L<=l && r<=R) return sum[x];
int mid=(l+r)>>1,ret=0;
if(L<=mid) ret+=query_sum(ls[x],l,mid,L,R);
if(mid<R) (ret+=query_sum(rs[x],mid+1,r,L,R))%=MOD;
return ret;
}
int query_num(int x,int l,int r,int L,int R){
if(!x) return 0; if(L<=l && r<=R) return num[x];
int mid=(l+r)>>1,ret=0;
if(L<=mid) ret+=query_num(ls[x],l,mid,L,R);
if(mid<R) (ret+=query_num(rs[x],mid+1,r,L,R))%=MOD;
return ret;
}
}tree2;
struct BIT{
inline void add(int x,int k){
for(int i=x;i<=n;i+=i&-i) {
tree2.update_num(rt[i],1,50000,a[x],k);
tree2.update_sum(rt[i],1,50000,a[x],k*val[x]);
}
}
inline int query_sum(int l,int r,int L,int R){
if(l>r || L>R) return 0; int ret=0;
for(int i=r;i;i-=i&-i) (ret+=tree2.query_sum(rt[i],1,50000,L,R))%=MOD;
for(int i=l-1;i;i-=i&-i) (ret-=tree2.query_sum(rt[i],1,50000,L,R))%=MOD;
return (ret+MOD)%MOD;
}
inline int query_num(int l,int r,int L,int R){
if(l>r || L>R) return 0; int ret=0;
for(int i=r;i;i-=i&-i) (ret+=tree2.query_num(rt[i],1,50000,L,R))%=MOD;
for(int i=l-1;i;i-=i&-i) (ret-=tree2.query_num(rt[i],1,50000,L,R))%=MOD;
return (ret+MOD)%MOD;
}
}tree1;
int main(){
n=rd(),m=rd(); int x,y,tmp,num,num1,num2;
for(int i=1;i<=n;i++){
a[i]=rd(),val[i]=rd(); tree1.add(i,1);
ans+=tree1.query_sum(1,i,a[i]+1,50000);
ans+=1ll*tree1.query_num(1,i,a[i]+1,50000)*val[i]%MOD;
ans%=MOD;
} LL sum;
while(m--){
x=rd(),y=rd(); if(x>y) swap(x,y);
if(x==y) {printf("%lld\n",ans); continue;}
if(a[x]<a[y]) (ans+=val[x]+val[y])%=MOD;
else (ans-=val[x]+val[y])%=MOD;
tmp=tree1.query_sum(x+1,y-1,min(a[x],a[y]),max(a[x],a[y]));
num=tree1.query_num(x+1,y-1,min(a[x],a[y]),max(a[x],a[y]));
num1=tree1.query_num(x+1,y-1,1,min(a[x],a[y])-1);
num2=tree1.query_num(x+1,y-1,max(a[x],a[y])+1,50000);
if(a[x]<a[y]) ans+=tmp*2%MOD+1ll*num*(val[x]+val[y])%MOD,ans%=MOD;
else ans-=tmp*2%MOD+1ll*num*(val[x]+val[y])%MOD,ans%=MOD;
sum=1ll*(val[y]-val[x])*num1%MOD+1ll*(val[x]-val[y])*num2%MOD; sum%=MOD;
(ans+=sum)%=MOD;
tree1.add(x,-1); tree1.add(y,-1); swap(a[x],a[y]); swap(val[x],val[y]);
tree1.add(x,1); tree1.add(y,1); ans=(ans+MOD)%MOD; printf("%lld\n",ans);
}
return 0;
}
LUOGU P3759 [TJOI2017]不勤劳的图书管理员(树套树)的更多相关文章
- 洛谷P3759 - [TJOI2017]不勤劳的图书管理员
Portal Description 给出一个\(1..n(n\leq5\times10^4)\)的排列\(\{a_n\}\)和数列\(\{w_n\}(w_i\leq10^5)\),进行\(m(m\l ...
- [P3759][TJOI2017]不勤劳的图书管理员(分块+树状数组)
题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生 这两本书页数的和的厌烦度.现在有n本被打乱顺序的书 ...
- 洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】
题目链接 洛谷P3759 题解 树状数组套主席树板题 #include<algorithm> #include<iostream> #include<cstring> ...
- Luogu 3759 [TJOI2017]不勤劳的图书管理员
再也不作死写FhqTreap作内层树了,卡的不如暴力呜呜呜…… 题意翻译:给一个序列,每个下标包含两个属性$a$和$v$,求第一个属性与下标形成的所有逆序对的第二个属性和,给出$m$个交换两个下标的操 ...
- P3759 [TJOI2017]不勤劳的图书管理员 [树套树]
树套树是什么啊我不知道/dk 我只知道卡常数w // by Isaunoya #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC o ...
- [TJOI2017]不勤劳的图书管理员(分块+树状数组)
有一个数组开大会MLE开小会RE的做法:就是树套树,即树状数组套主席树,这种方法比较暴力,然而很遗憾它不能通过,因为其时空复杂度均为O(nlog2n). 想到一种不怎么耗内存,以时间换空间,分块!单次 ...
- 【bzoj4889】: [Tjoi2017]不勤劳的图书管理员 分块-BIT
[bzoj4889]: [Tjoi2017]不勤劳的图书管理员 题目大意:给定一个序列(n<=50000),每个数有一个编码ai(ai<=50000)和权值vi(vi<=100000 ...
- 【BZOJ4889】[Tjoi2017]不勤劳的图书管理员 分块+树状数组
[BZOJ4889][Tjoi2017]不勤劳的图书管理员 题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让 ...
- 【loj2639】[Tjoi2017]不勤劳的图书管理员
#2639. 「TJOI2017」不勤劳的图书管理员 题目描述 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产 ...
随机推荐
- windows mysql官方绿色版zip包安装教程
环境: 系统环境 Windows 10 64位 mysql版本 5.7.19 一.万变不离的下载 下载页面:https://dev.mysql.com/downloads/mysql/ 点击 Down ...
- Nginx 配置 location 以及 return、rewrite 和 try_files 指令
正则表达式 Nginx 内置的全局变量 location 前缀字符串及优先级 示例 location 匹配原则 if 和 break 指令 if break return.rewrite 和 try_ ...
- php脚本超时时间设置
设置PHP脚本执行超时的时间有下面这样一些方法:php.ini 中缺省的最长执行时间是 30 秒,这是由 php.ini 中的 max_execution_time 变量指定,倘若你有一个需要颇多时间 ...
- JQuery 字符串转时间格式
//字符串转时间格式 function getDate(strDate) { var date = eval('new Date(' + strDate.replace(/\d+(?=-[^-]+$) ...
- cts-verifier测试流程
测试目的: cts的补充测试,可以理解为没法自动化的cts测试,这个是人工测试. 测试前提: 1.发货user版本 2.selinux:Enable 5.外网环境 设备需求: 2个待测设备:1个手机或 ...
- hdu2602Bone Collector ——动态规划(0/1背包问题)
Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bone Collec ...
- SPOJ NICEBTRE - Nice Binary Trees(树 先序遍历)
传送门 Description Binary trees can sometimes be very difficult to work with. Fortunately, there is a c ...
- HTML5--浏览器全屏操作、退出全屏、是否全屏
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 《JAVA设计模式》之抽象工厂模式(Abstract Factory)
场景问题 举个生活中常见的例子——组装电脑,我们在组装电脑的时候,通常需要选择一系列的配件,比如CPU.硬盘.内存.主板.电源.机箱等.为讨论使用简单点,只考虑选择CPU和主板的问题. 事实上,在选择 ...
- P4843 清理雪道(上下界网络流)
P4843 清理雪道 上下界最小流 我们先搞一遍上下界可行流(转) 回忆上下界最大流的写法:在可行流的残量网络$s\ -\ t$上跑最大流,答案为可行流$+$残量网络的最大流 那么上下界最小流的写法呢 ...