[BJOI2017]开车
直接做要用栈
修改?难以直接维护
统计边的贡献!
len*abs(pre)pre表示前缀car-stop
修改时候,整个区间的pre+1或者-1
分块,块内对pre排序并打标记
二分出0的位置,再根据pre的正负和本次是+1,-1,leni贡献+1还是-1的贡献
O(nsqrt(n)logn)
- #include<bits/stdc++.h>
- #define reg register int
- #define il inline
- #define fi first
- #define se second
- #define mk(a,b) make_pair(a,b)
- #define numb (ch^'0')
- using namespace std;
- typedef long long ll;
- template<class T>il void rd(T &x){
- char ch;x=;bool fl=false;
- while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
- for(x=numb;isdigit(ch=getchar());x=x*+numb);
- (fl==true)&&(x=-x);
- }
- template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
- template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
- template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
- namespace Miracle{
- const int N=*5e4+;
- const int B=;
- int n,m;
- int L[N],R[N];
- struct qs{
- int id,x;
- }q[N];
- int c[N],cnt;
- int tot;
- int pos[N],b[N];
- int be[N],len[N];
- vector<int>mem[B],sum[B];
- int tag[B];
- ll con[B];
- int exi[N];//0: none 1:car -1:stop
- int pre[N];
- int buc[N];
- bool cmp(int x,int y){
- return pre[x]<pre[y];
- }
- int li(int x){
- return lower_bound(c+,c+cnt+,x)-c;
- }
- int main(){
- rd(n);
- for(reg i=;i<=n;++i) rd(pos[i]),c[++cnt]=pos[i];
- for(reg i=;i<=n;++i) rd(b[i]),c[++cnt]=b[i];
- rd(m);
- for(reg i=;i<=m;++i){
- rd(q[i].id);rd(q[i].x);
- c[++cnt]=q[i].x;
- }
- sort(c+,c+cnt+);
- cnt=unique(c+,c+cnt+)-c-;
- int blo=sqrt(cnt)+;
- for(reg i=;i<=cnt;++i){
- be[i]=(i-)/blo+;
- if(!L[be[i]]) L[be[i]]=i;
- R[be[i]]=i;
- len[i]=c[i+]-c[i];
- }
- len[cnt]=;
- tot=be[cnt];
- for(reg i=;i<=n;++i){
- int po=lower_bound(c+,c+cnt+,b[i])-c;
- --exi[po];
- po=lower_bound(c+,c+cnt+,pos[i])-c;
- ++exi[po];
- }
- ll ans=;
- for(reg i=;i<=cnt;++i){
- pre[i]=pre[i-]+exi[i];
- ans+=(ll)len[i]*abs(pre[i]);
- }
- for(reg j=;j<=tot;++j){
- tag[j]=;
- for(reg i=L[j];i<=R[j];++i){
- mem[j].push_back(i);
- con[j]+=(ll)len[i]*abs(pre[i]);
- }
- sort(mem[j].begin(),mem[j].end(),cmp);
- sum[j].resize(mem[j].size());
- for(reg i=;i<(int)mem[j].size();++i){
- sum[j][i]=len[mem[j][i]];
- if(i) sum[j][i]+=sum[j][i-];
- }
- }
- printf("%lld\n",ans);
- for(reg o=;o<=m;++o){
- int l=li(pos[q[o].id]),r=li(q[o].x);
- exi[l]--;exi[r]++;
- int c=-;//l->r
- if(l>r) swap(l,r),c=;//r->l
- --r;//warinig!!!
- if(be[l]==be[r]){
- for(reg i=l;i<=r;++i) pre[i]+=c;
- ans-=con[be[l]];
- con[be[l]]=;
- mem[be[l]].clear();
- sum[be[l]].clear();
- int j=be[l];
- for(reg i=L[be[l]];i<=R[be[l]];++i){
- pre[i]+=tag[be[l]];
- mem[j].push_back(i);
- }
- sort(mem[j].begin(),mem[j].end(),cmp);
- sum[j].resize(mem[j].size());
- for(reg i=;i<(int)mem[j].size();++i){
- sum[j][i]=len[mem[j][i]];
- con[j]+=(ll)len[mem[j][i]]*abs(pre[mem[j][i]]);
- if(i) sum[j][i]+=sum[j][i-];
- }
- tag[be[l]]=;
- ans+=con[be[l]];
- }else{
- for(reg i=l;i<=R[be[l]];++i){
- pre[i]+=c;
- }
- int j=be[l];
- ans-=con[j];
- con[j]=;
- mem[j].clear();
- sum[j].clear();
- for(reg i=L[j];i<=R[j];++i){
- pre[i]+=tag[j];
- mem[j].push_back(i);
- }
- sort(mem[j].begin(),mem[j].end(),cmp);
- sum[j].resize(mem[j].size());
- for(reg i=;i<(int)mem[j].size();++i){
- sum[j][i]=len[mem[j][i]];
- con[j]+=(ll)len[mem[j][i]]*abs(pre[mem[j][i]]);
- if(i) sum[j][i]+=sum[j][i-];
- }
- tag[j]=;
- ans+=con[j];
- for(reg i=L[be[r]];i<=r;++i){
- pre[i]+=c;
- }
- j=be[r];
- ans-=con[j];
- con[j]=;
- mem[j].clear();
- sum[j].clear();
- for(reg i=L[j];i<=R[j];++i){
- pre[i]+=tag[j];
- mem[j].push_back(i);
- }
- sort(mem[j].begin(),mem[j].end(),cmp);
- sum[j].resize(mem[j].size());
- for(reg i=;i<(int)mem[j].size();++i){
- sum[j][i]=len[mem[j][i]];
- con[j]+=(ll)len[mem[j][i]]*abs(pre[mem[j][i]]);
- if(i) sum[j][i]+=sum[j][i-];
- }
- tag[j]=;
- ans+=con[j];
- for(reg j=be[l]+;j<=be[r]-;++j){
- pre[]=-tag[j];
- if(c==-){
- int lp=upper_bound(mem[j].begin(),mem[j].end(),,cmp)-mem[j].begin();
- --lp;//warning!! maybe -1
- if(lp!=-){
- ans+=(ll)sum[j][lp];
- ans-=(ll)sum[j][mem[j].size()-]-sum[j][lp];
- con[j]+=(ll)sum[j][lp];
- con[j]-=(ll)sum[j][mem[j].size()-]-sum[j][lp];
- }else{
- ans-=(ll)sum[j][mem[j].size()-];
- con[j]-=(ll)sum[j][mem[j].size()-];
- }
- }else{
- int lp=lower_bound(mem[j].begin(),mem[j].end(),,cmp)-mem[j].begin();
- --lp;//warning!! maybe -1
- if(lp!=-){
- ans-=(ll)sum[j][lp];
- ans+=(ll)sum[j][mem[j].size()-]-sum[j][lp];
- con[j]-=(ll)sum[j][lp];
- con[j]+=(ll)sum[j][mem[j].size()-]-sum[j][lp];
- }else{
- ans+=(ll)sum[j][mem[j].size()-];
- con[j]+=(ll)sum[j][mem[j].size()-];
- }
- }
- tag[j]+=c;
- }
- pre[]=;
- }
- pos[q[o].id]=q[o].x;
- printf("%lld\n",ans);
- }
- return ;
- }
- }
- signed main(){
- Miracle::main();
- return ;
- }
- /*
- Author: *Miracle*
- Date: 2019/4/11 10:31:35
- */
[BJOI2017]开车的更多相关文章
- 题解 [BJOI2017]开车
题目传送门 题目大意 有\(n\)个汽车和\(n\)个加油站,坐标分别为\(a_{1,2,...,n}\)和\(b_{1,2,...,n}\).每辆汽车会到一个加油站,求出最小移动距离之和.有\(m\ ...
- vijos P1780 【NOIP2012】 开车旅行
描述 小\(A\)和小\(B\)决定利用假期外出旅行,他们将想去的城市从\(1\)到\(N\)编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市\(i\)的海拔高度为 ...
- [NOIP2012] 提高组 洛谷P1081 开车旅行
题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...
- 豆制品厂开车超市送货智能手持PDA POS打票机-手持票据打印机
豆制品厂开车拉着豆腐到某一个超市送货,到达后秤出斤数后就用票据打印机开单 能直接开单,单子一式两份,一张给客户一张留底,到月底时客户要根据客户的量返点的,单子统计.能现场开单,单子上显示哪个超市,豆制 ...
- 在包a中编写一个类Father,具有属性:年龄(私有)、姓名(公有); 具有功能:工作(公有)、开车(公有)。 在包a中编写一个子类Son,具有属性:年龄(受保护的)、姓名; 具有功能:玩(私有)、学习(公有)。 最后在包b中编写主类Test,在主类的main方法中测试类Father与类Son。
package a; public class Father { public String name; private int age; public Father(String name) { t ...
- 【noip2012】开车旅行
题意: 给n个点的海拔h[i](不同点海拔不同) 两点的距离为abs(h[i]-h[j]) 有a.b两人轮流开车(只能往下标大的地方开) a每次会开到里当前点第二近的点 b每次会开到离当前点最近的点( ...
- 【NOIP 2012 开车旅行】***
题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...
- javascript 老王开车去东北
[Decode error - output not utf-8] 魔女 飞 奔驰 去 华南 [Finished in 1.1s] 需要变化的对象进行隔离.正是编程的乐趣之处 /** * by Jac ...
- 【NOIP2012】开车旅行(倍增)
题面 Description 小A 和小B决定利用假期外出旅行,他们将想去的城市从1到N 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i的海拔高度为Hi,城市 ...
随机推荐
- spring mvc常用注解总结
1.@RequestMapping@RequestMappingRequestMapping是一个用来处理请求地址映射的注解(将请求映射到对应的控制器方法中),可用于类或方法上.用于类上,表示类中的所 ...
- Laravel5.5+ 区分前后端用户登录
Laravel 的用户认证是通过 Auth Facade 门脸实现的,手动认证可是使用 Auth::login() 或 Auth::attempt() 这两个方法实现. 以下内容纯属个人实现,也许有 ...
- java回调机制——基本理解
回调(diao):往回调用,反向调用. 英文 call back.call:调用,back:返回,往返. 回调的意思就是杀个回马枪...... 回调(callback),既然是往回调用,那自然有一个正 ...
- ajax获取值的两种方法
详细连接https://blog.csdn.net/a1102325298/article/details/80785143 ajax获得表单值的俩种方法 2018年06月23日 17:12:02 延 ...
- Linux基础学习笔记6-SHELL编程
编程基础 程序:指令+数据 程序编程风格: 过程式:以指令为中心,数据服务于指令 对象式:以数据为中心,指令服务于数据 shell程序:提供了编程能力,解释执行 编程基本概念: 顺序执行:循环执行:选 ...
- Delphi 工具条按钮上的下拉菜单
制作步骤: 1.添加一个 TImageList: ImageList1, 然后载入些图标; 2.添加两个 TPopupMenu: PopupMenu1.PopupMenu2, 并分别添加些菜单项; 3 ...
- Python——Flask框架——数据库
一.数据库框架 Flask-SQLAlchemy (1)安装: pip install flask-sqlalchemy (2)Flask-SQLAlchemy数据库URL 数据库引擎 URL MyS ...
- Lodop打印设计、维护、预览、直接打印简单介绍
四者的区别和联系:(其中PRINT_DESIGN打印设计是提供给开发人员的,另外三个可开放给用户)PRINT_DESIGN打印设计:辅助开发人员设计,图形化拖动插入修改等,设计完成后,生成代码拷贝到程 ...
- oracle复习(二)
十一.replace 替换格式:(原字符串,要查找的字符或字符串,替换的字符或字符串)select replace('hello world','o','a') from dual; //替换时区分大 ...
- js弹框的3种方法
js的三种弹框的方法 1.第一种 : alert("1"); 2.第二种 : window.open("Tests2.html"); var r = con ...