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

2024-03-19 17:58

本文主要是介绍洛谷P3759 - [TJOI2017]不勤劳的图书管理员,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Portal

Description

给出一个\(1..n(n\leq5\times10^4)\)的排列\(\{a_n\}\)和数列\(\{w_n\}(w_i\leq10^5)\),进行\(m(m\leq5\times10^4)\)次操作:
交换\(a_{p_1},a_{p_2}\),并求\(\sum_{i=1}^n \sum_{j=i+1}^n [a_i>a_j](w_{a_i}+w_{a_j})\)

Solution

树套树/CDQ分治,想锻炼一下代码能力所以写了树套树。
首先这是一个求逆序对的问题,那么我们考虑交换\(a_{p_1},a_{p_2}\)对答案有什么影响。易知只有\(i\in[p_1+1,p_2-1]\)对答案造成影响:
\(a_i<a_{p_1}\),那么答案减\(a_i+a_{p_1}\);若\(a_i>a_{p_1}\),那么答案加\(a_i+a_{p_1}\)
\(a_i<a_{p_2}\),那么答案加\(a_i+a_{p_2}\);若\(a_i>a_{p_2}\),那么答案减\(a_i+a_{p_2}\)
那么求出\(\{c_1,s_1,c_2,s_2\}\)分别表示区间\([p_1+1,p_2-1]\)内小于/大于\(x\)\(i\)的个数/\(w_i\)的和,然后就可以根据上两行计算答案的变化。而这可以用树套树来做。

时间复杂度\(O(mlog^2n)\)

Code

//[TJOI2017]不勤劳的图书管理员
#include <algorithm>
#include <cstdio>
using std::swap;
typedef long long lint;
inline char gc()
{static char now[1<<16],*s,*t;if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}return *s++;
}
inline int read()
{int x=0; char ch=gc();while(ch<'0'||'9'<ch) ch=gc();while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();return x;
}
const int N=5e4+10;
const int P=1e9+7;
int n,m,a[N],w[N];
namespace init
{int tr1[N],tr2[N];void add(int x,int v) {while(x<=n) tr1[x]++,tr2[x]=(tr2[x]+v)%P,x+=x&(-x);}int sum1(int x) {int r=0; while(x) r+=tr1[x],x-=x&(-x); return r;}int sum2(int x) {int r=0; while(x) r=(r+tr2[x])%P,x-=x&(-x); return r;}int calc(){int res=0;for(int i=1;i<=n;i++){res=(res+(lint)sum1(n-a[i]+1)*w[a[i]])%P;res=(res+sum2(n-a[i]+1))%P;add(n-a[i]+1,w[a[i]]);}return res;}
}
const int N1=2e6;
struct info
{int c1,s1,c2,s2;info(int _c1=0,int _s1=0,int _c2=0,int _s2=0) {c1=_c1,s1=_s1,c2=_c2,s2=_s2;};friend info operator +(info x,info y){int c1=x.c1+y.c1,s1=x.s1+y.s1,c2=x.c2+y.c2,s2=x.s2+y.s2;return info(c1,s1%P,c2,s2%P);}
};
namespace inTr
{int cnt,fa[N1],ch[N1][2],siz[N1]; int val[N1],sum[N1];inline void update(int p){siz[p]=siz[ch[p][0]]+1+siz[ch[p][1]];sum[p]=((sum[ch[p][0]]+sum[ch[p][1]])%P+w[val[p]])%P;}inline int wh(int p) {return p==ch[fa[p]][1];}inline void rotate(int p){int q=fa[p],r=fa[q],w=wh(p);fa[p]=r; if(r) ch[r][wh(q)]=p;fa[ch[q][w]=ch[p][w^1]]=q;fa[ch[p][w^1]=q]=p;update(q),update(p);}void splay(int &rt,int p){for(int q=fa[p];q;rotate(p),q=fa[p]) if(fa[q]) rotate(wh(p)^wh(q)?p:q);update(rt=p);}int pre(int rt,int x){int r=0;for(int p=rt;p;p=ch[p][val[p]<x]) if(val[p]<x) r=p;return r;}void ins(int &rt,int p){if(!rt) {rt=p; return;}int q=rt;while(ch[q][val[q]<val[p]]) q=ch[q][val[q]<val[p]];fa[ch[q][val[q]<val[p]]=p]=q;update(q); splay(rt,p);}int del(int &rt,int x){if(x==0||!rt) return 0;int p=pre(rt,x+1); if(val[p]!=x) return 0;splay(rt,p);int chCnt=(ch[p][0]>0)+(ch[p][1]>0);if(chCnt==0) {rt=0; return p;}if(chCnt==1) {rt=ch[p][ch[p][1]>0],fa[rt]=0; return p;}int q=ch[p][0]; while(ch[q][1]) q=ch[q][1];splay(rt,q);fa[ch[q][1]=ch[p][1]]=q;fa[p]=ch[p][0]=ch[p][1]=0;update(q);return p;}inline void change(int &rt,int x1,int x2){int p=del(rt,x1); if(!p) p=++cnt;fa[p]=ch[p][0]=ch[p][1]=0,siz[p]=1;val[p]=x2,sum[p]=w[x2];ins(rt,p);}info query(int rt,int x){int c1=0,s1=0;for(int p=rt;p;p=ch[p][val[p]<x])if(val[p]<x) c1+=siz[p]-siz[ch[p][1]],s1=(s1+sum[p]-sum[ch[p][1]]+P)%P;return info(c1,s1,siz[rt]-c1,sum[rt]-s1);}
}
namespace outTr
{#define Ls (p<<1)#define Rs (p<<1|1)int rt[N<<2];int in(int L,int R,int p1,int p2) {return ((L<=p2&&p2<=R)<<1)|(L<=p1&&p1<=R);}void change(int p,int L0,int R0,int p1,int p2){int inP=in(L0,R0,p1,p2);if(inP==1) inTr::change(rt[p],a[p1],a[p2]);else if(inP==2) inTr::change(rt[p],a[p2],a[p1]);if(L0==R0) return;int mid=L0+R0>>1;if(in(L0,mid,p1,p2)) change(Ls,L0,mid,p1,p2);if(in(mid+1,R0,p1,p2)) change(Rs,mid+1,R0,p1,p2);}int optL,optR;info query(int p,int L0,int R0,int x){if(optL<=L0&&R0<=optR) return inTr::query(rt[p],x);int mid=L0+R0>>1; info res=info(0,0,0,0);if(optL<=mid) res=res+query(Ls,L0,mid,x);if(mid<optR) res=res+query(Rs,mid+1,R0,x);return res;}
}
inline void change(int p1,int p2) {outTr::change(1,1,n,p1,p2);}
inline info query(int L,int R,int x)
{outTr::optL=L,outTr::optR=R;return outTr::query(1,1,n,x);
}
int main()
{n=read(),m=read();for(int i=1;i<=n;i++){a[0]=read(),w[a[0]]=read();change(0,i); swap(a[0],a[i]);}int ans=init::calc();for(int i=1;i<=m;i++){int p1=read(),p2=read();if(p1>p2) swap(p1,p2); else if(p1==p2) {printf("%d\n",ans); continue;}int x=a[p1],y=a[p2];info r1=query(p1+1,p2-1,x),r2=query(p1+1,p2-1,y);ans-=((lint)r1.c1*w[x]%P+r1.s1)%P; ans=(ans+P)%P;ans+=((lint)r1.c2*w[x]%P+r1.s2)%P; ans=ans%P;ans+=((lint)r2.c1*w[y]%P+r2.s1)%P; ans=ans%P;ans-=((lint)r2.c2*w[y]%P+r2.s2)%P; ans=(ans+P)%P;if(x<y) ans=(ans+w[x]+w[y])%P; else ans=(ans-w[x]-w[y]+P)%P;printf("%d\n",ans);change(p1,p2); swap(a[p1],a[p2]);}return 0;
}

转载于:https://www.cnblogs.com/VisJiao/p/LgP3759.html

这篇关于洛谷P3759 - [TJOI2017]不勤劳的图书管理员的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/826819

相关文章

图书管理系统系统分享

分享一个图书管理系统,Java、SpringBoot、Vue和MySQL开发的图书馆管理系统 gitee项目地址:https://gitee.com/yuanmomoya/open-source-project/tree/master/books-management-system GitHub项目地址:https://github.com/yuanmomoya/open-source-pro

基于springboot+vue+uniapp的“共享书角”图书借还管理系统小程序

开发语言:Java框架:springboot+uniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9 系统展示 后台登录界面 管理员功能界面 出借者管理 图书信息管理 图书归还管理 出租收入管理

高精度计算(代码加解析,洛谷p1601,p1303)除法待更新

目录 高精度加法 高精度减法 高精度乘法 高精度加法 我们知道在c++语言中任何数据类型都有一定的表示范围。当两个被加数很大时,正常加法不能得到精确解。在小学,我们做加法都采用竖式方法。那么我们也只需要按照加法进位的方式就能得到最终解。 8 5 6+ 2 5 5-------1 1 1 1 加法进位: c[i] = a[i] + b[i];if(c[i] >=

洛谷 凸多边形划分

T282062 凸多边形的划分 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 先整一个半成品,高精度过两天复习一下补上 #include <iostream>#include <algorithm>#include <set>#include <cstring>#include <string>#include <vector>#include <map>

能量项链,洛谷

解释:  环形dp问题还是考虑将环拉直,可以参考我上一篇文章:环形石子合并 [2 3 5 10 2] 3 5 10 将环拉直,[]内是一个有效的区间,可以模拟吸收珠子的过程,         如[2 3 5] <=>(2,3)(3,5)    2是头,3是中间,5是尾 len >= 3:因为最后[2 10 2]是最小的可以合并的有效区间 len <= n + 1因为[2 3

当当图书福利券,满400减230,别说我没告诉你!

1024程序员节 当当网计算机图书 每满100减50! 满200减100! 满300-150! 机械工业出版社华章公司联合当当网特意为【大数据技术与架构】用户申请了一批可与满减叠加使用的“满200减30”的图书优惠码,优惠码使用后相当于: 400减230 !!!   优惠码:【YRMQMY】(注意区分大小写) 使用渠道:当当app和当当小程序 使用时间:10月22-10月31 本活动满减与礼券

智能图书推荐系统:Spring Boot技术深度解析

4 系统设计 4.1系统概要设计 本图书个性化推荐系统选择B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式。适合在互联网上进行操作,只要学生能连网,任何时间、任何地点都可以进行系统的操作使用。系统工作原理图如图4-1所示: 图4-1 系统工作原理图 4.2系统结构设计 整个系统是由多个功能模块组合而成的,要将所有的功能模块都一一列举出来,然后进行逐个的功能

个性化阅读体验:Spring Boot框架的图书推荐解决方案

第5章 系统详细设计 5.1前台首页功能模块 图书个性化推荐系统,在前台首页可以查看首页、图书信息、好书推荐、留言反馈、个人中心、后台管理等内容,如图5-1所示。 图5-1首页功能界面图 学生注册、登录,在学生注册页面可以填写学号、密码、学生姓名、性别、出生日期、联系电话、班级等信息进行注册、登录,如图5-2所示。 图5-2学生注册、登录界面图 图书信息,在图书信息页面通过查看图书

数据库课程设计mysql---图书管理系统详细的设计文档和需求文档

图书管理系统设计文档与需求文档 一、项目概述 项目名称:图书管理系统 项目背景:随着图书馆规模的扩大和图书数量的增加,传统的手工管理方式已难以满足现代图书馆高效、精准的管理需求。因此,开发一套基于MySQL的图书管理系统,旨在通过信息化手段实现图书的录入、借阅、归还、查询及用户管理等功能的自动化,提高图书馆的工作效率和服务质量。 项目目标: 实现图书信息的电子化存储与管理。提供便捷的图书

爬虫一:获取豆瓣图书Top250(Requests+XPath)

目的: 获取豆瓣图书Top250的所有书目信息。 豆瓣网址:https://book.douban.com/top250 代码: import requestsfrom lxml import etreeimport timefor i in range(10):url = 'https://book.douban.com/top250?start=' + str(25*i)data