传送门

解题思路

  和以前做过的一道题有点像,就是区间逆序对之类的问题,用的是\(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]不勤劳的图书管理员(树套树)的更多相关文章

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

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

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

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

  3. 洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】

    题目链接 洛谷P3759 题解 树状数组套主席树板题 #include<algorithm> #include<iostream> #include<cstring> ...

  4. Luogu 3759 [TJOI2017]不勤劳的图书管理员

    再也不作死写FhqTreap作内层树了,卡的不如暴力呜呜呜…… 题意翻译:给一个序列,每个下标包含两个属性$a$和$v$,求第一个属性与下标形成的所有逆序对的第二个属性和,给出$m$个交换两个下标的操 ...

  5. P3759 [TJOI2017]不勤劳的图书管理员 [树套树]

    树套树是什么啊我不知道/dk 我只知道卡常数w // by Isaunoya #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC o ...

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

    有一个数组开大会MLE开小会RE的做法:就是树套树,即树状数组套主席树,这种方法比较暴力,然而很遗憾它不能通过,因为其时空复杂度均为O(nlog2n). 想到一种不怎么耗内存,以时间换空间,分块!单次 ...

  7. 【bzoj4889】: [Tjoi2017]不勤劳的图书管理员 分块-BIT

    [bzoj4889]: [Tjoi2017]不勤劳的图书管理员 题目大意:给定一个序列(n<=50000),每个数有一个编码ai(ai<=50000)和权值vi(vi<=100000 ...

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

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

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

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

随机推荐

  1. Failed to load resource: the server responsed with a status of 400 (Bad Request)

    浏览器报错:Failed to load resource: the server responsed with a status of 400 (Bad Request) ajax请求失败,一般情况 ...

  2. PHP 调试 - Xdebug

    PHP 调试指南.pdf PHP 程序员的调试技术 根据要调试的对象的不同,采取的方法也不一样: 调试 web 应用:对于 web 应用,可以在浏览器中安装插件,或者在 IDE 中设置,下面的设置二选 ...

  3. redis连接报错:MISCONF Redis is configured to save RDB snapshots, but it is currently not able to...

    连接redis报错: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persis ...

  4. .NET简单三层的理解

    1.UI 表示层 :就是我们看到的网站前台2.BLL 业务逻辑层:很简单 也很重要 处理逻辑问题 简单程序看不出啥效果3.DAL 数据访问层: 写数据连接和执行的SQL语句4.MODEL 模型层:封装 ...

  5. Requests爬取网页的编码问题

    Requests爬取网页的编码问题 import requests from requests import exceptions def getHtml(): try: r=requests.get ...

  6. Learning OSG programing---osgAnimation(3)

    接下来是用createModel函数创建模型: osg::ref_ptr<osg::Group> createModel(bool overlay, osgSim::OverlayNode ...

  7. Spring Security 04

    转至:Elim的博客http://elim.iteye.com/blog/2161648 Filter Porxy DelegatingFilterProxy DelegationFilterProx ...

  8. oracle用户权限管理

    oralce对权限管理比较严谨,普通用户之间也是默认不能互相访问的,需要互相授权 1.查看当前数据库所有用户: select * from all_users; 2.查看表所支持的权限: select ...

  9. [洛谷P3261] [JLOI2015]城池攻占(左偏树)

    不得不说,这道题目是真的难,真不愧它的“省选/NOI-”的紫色大火题!!! 花了我晚自习前半节课看题解,写代码,又花了我半节晚自习调代码,真的心态爆炸.基本上改得和题解完全一样了我才过了这道题!真的烦 ...

  10. python 丰田经销商

    import requests import json from dbutil.pgsql import PgsqlPipeline from datetime import date headers ...