【XSY2762】插线板 分块
题目大意
有\(n\)个插线板,每个插线板会在\(l_i\)时刻初插入到队列中(队列是按插线板的编号排序的),\(r_i\)时刻末移除。
插入一个插线板时会对当前所有接在队列中这个插线的下一个插线板上的用电器造成\(1\)的代价。
有\(q\)个询问,每次给你\(x,y\),问你你要在\(x\)时刻把用电器接在插线板上,\(y\)时刻移除,最少的代价是多少。
\(n,q\leq 50000\)
题解
先处理每个时刻那个插线板上的用电器得到了\(1\)的代价。这个东西的总和是\(O(n)\)的。
可以用分块在\(O(n\sqrt n)\)内预处理,\(O(1)\)查询如果把用电器接在一个插线板上,那么代价是多少。
按时间分块,预处理出每一块的左端点到右边任意一个点的答案。
可以枚举左端点然后从最右边往左扫一遍,维护当前的最小值。
那么对于一个询问\(x,y\),找到包含这个询问左端点的块的左端点\(l\),那么答案只有可能是三种情况:
1.询问\([l,y]\)的答案,这个已经处理好了。
2.插到一个在\([l,x]\)中有修改的插线板上。
3.插到一个在\([l,x]\)中插入的插线板上。
暴力统计即可。
取块大小\(size=\sqrt n\)可以得到最优时间复杂度\(O((n+q)\sqrt n)\)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<utility>
using namespace std;
int rd()
{
int s,c;
while((c=getchar())<'0'||c>'9');
s=c-'0';
while((c=getchar())>='0'&&c<='9')
s=s*10+c-'0';
return s;
}
typedef pair<int,int> pii;
const int inf=0x3fffffff;
set<int> st;
int b1[100010];
int b2[100010];
void add(int x,int y)
{
set<int>::iterator p=st.lower_bound(x);
if(p!=st.end())
b1[y]=*p;
}
int al[100010];
int ar[100010];
pii c[100010];
const int N=100000;
const int size=500;
struct orz
{
int s1[N/size+1];
int *s2[N/size+1];
orz()
{
memset(s1,0,sizeof s1);
memset(s2,0,sizeof s2);
}
void add(int x)
{
int bl=x/size;
for(int i=bl+1;i<=N/size;i++)
s1[i]++;
int *&t=s2[bl];
if(!t)
{
t=new int[size];
for(int i=0;i<size;i++)
t[i]=0;
}
for(int i=x%size;i<size;i++)
t[i]++;
}
int query(int x)
{
int s=0;
s+=s1[x/size];
if(s2[x/size])
s+=s2[x/size][x%size];
return s;
}
};
orz bl[50010];
int sum[50010];
int s[N/size+1][100010];
int main()
{
#ifndef ONLINE_JUDGE
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
#endif
int n,m,q,type;
scanf("%d%d%d%d",&n,&m,&q,&type);
for(int i=1;i<=n;i++)
{
al[i]=rd();
ar[i]=rd();
c[al[i]]=pii(i,1);
c[ar[i]]=pii(i,2);
}
for(int i=1;i<=m;i++)
if(c[i].first)
{
b2[i]=c[i].first;
if(c[i].second==1)
{
add(c[i].first,i);
st.insert(c[i].first);
}
else
{
st.erase(c[i].first);
add(c[i].first,i);
}
}
for(int i=1;i<=m;i++)
if(b1[i])
{
if(c[i].second==1)
bl[b1[i]].add(i);
else
bl[b1[i]].add(i+1);
}
for(int i=1;i<=m;i+=size)
{
for(int j=i;j<=m;j++)
if(b1[j])
sum[b1[j]]++;
int now=inf;
for(int j=m;j>=i;j--)
{
if(c[j].second==2&&al[b2[j]]<=i)
now=min(now,sum[b2[j]]);
if(c[j].second==2&&b1[j])
{
sum[b1[j]]--;
if(al[b1[j]]<=i)
now=min(now,sum[b1[j]]);
}
s[(i-1)/size][j]=now;
if(c[j].second==1&&b1[j])
{
sum[b1[j]]--;
if(al[b1[j]]<=i)
now=min(now,sum[b1[j]]);
}
}
}
int x,y;
int last=0;
for(int i=1;i<=q;i++)
{
x=rd();
y=rd();
if(type)
{
x^=last;
y^=last;
}
int ans=s[(x-1)/size][y];
for(int j=(x-1)/size*size+1;j<=x;j++)
{
if(ar[b1[j]]>=y)
ans=min(ans,bl[b1[j]].query(y)-bl[b1[j]].query(x));
if(ar[b2[j]]>=y)
ans=min(ans,bl[b2[j]].query(y)-bl[b2[j]].query(x));
}
if(ans==inf)
ans=-1;
printf("%d\n",ans);
if(ans==-1)
last=0;
else
last=ans;
}
return 0;
}
【XSY2762】插线板 分块的更多相关文章
- xcoj 1103 插线板(树链刨分求最大子段和)
1103: 插线板 时间限制: 1 Sec 内存限制: 128 MB提交: 14 解决: 7 标签提交统计讨论版EditTestData 题目描述 从前有一堆古老的插线板,任意两个插线板之间只有一 ...
- poj2636---Electrical Outlets(插线板)
#include <stdio.h> #include <stdlib.h> int main() { int n,nc,i; scanf("%d",&am ...
- NOIWC2018游记
NOIWC2018游记 接着PKUWC就是NOIWC了.感觉时间很紧呀,但越是紧张呢,就越让人心里觉得充实. 能够去NOIWC,应该是一次非常充实的体验吧. 这一篇游记是接着上一篇写的,时间点上完全都 ...
- 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型
前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...
- 什么是RAID?RAID有什么用?RAID原理
什么是RAID 硬盘是个很脆弱的东西,它经常会坏掉.所以,为了保证服务器可靠耐用,硬盘必须时时刻刻保持可用.所以有了RAID这个东西.它的目的是将好几个硬盘合并在一起,就算硬盘坏了一个,剩下还有好几个 ...
- Windows Azure HandBook (1) IaaS相关技术
<Windows Azure Platform 系列文章目录> 1.Microsoft Azure底层是否由System Center和Hyper-V构成? Microsoft Azure ...
- XCOJ 1103 (LCA+树链最大子段和)
题目链接: http://xcacm.hfut.edu.cn/problem.php?id=1103 题目大意:链更新.链查询,求树链的最大子段和.(子段可以为空) 解题思路: 将所有Query离线存 ...
- 20145218&20145240 《信息安全系统设计基础》实验一 开发环境的熟悉
20145218&20145240 <信息安全系统设计基础>实验一 开发环境的熟悉 课程:信息安全系统设计基础 班级:1452 姓名:(按贡献大小排名)刘士嘉 张晓涵 学号:(按贡 ...
- 信息安全系统设计基础实验一 20135211&20135216
北京电子科技学院(BESTI) 实 验 报 告 封面 课程:信息安全系统设计基础 班级:1352 姓名:(按贡献大小排名)李行之 刘蔚然 ...
随机推荐
- C++与Java,C#的异同(一):值,地址,引用
Java,C#已经比较熟悉,最近在从0开始自学C++.学习过程中必然会与Java,C#进行对比,有吐槽,也有点赞. 先来讲讲最基本也是最重要的部分:参数传递的方式. 对于类型, Java分基本类型.复 ...
- struts2的基本使用
struts2在web中当作前端控制器,接收来自页面的请求,使用过滤器拦截模式对请求进行拦截并交给相应配置的action类处理. 所以在web中使用最重要的是struts2的核心过滤器StrutsPr ...
- c++入门之类与内存
类作为c++编程的核心,自然我们十分关注其内存分配问题. 这里的这个主题中,我们关注了静态成员,new,delete.还有构造函数和析构函数. 先上代码: # include "iostre ...
- Day15 Python基础之logging模块(十三)
参考源:http://www.cnblogs.com/yuanchenqi/articles/5732581.html logging模块 (****重点***) 一 (简单应用) import lo ...
- MySQL分页时统计总记录行数并使用limit返回固定数目的记录
需求很简单:假设有一个user表,表中实际上有10000条数据,但是我不知道有多少条,我要从数据库中每次取20条数据显示,那么怎么完成呢? 方案一: 首先执行一个 select count(*) as ...
- gethostbyname用法
//会优先查询解析%windir%\system32\drivers\etc\hosts中静态dns表 //一个域名可对应多个IP hostent->h_addr_list ==> 是in ...
- mysql_linux(centos7 mysql 5.7.19)
centos7 mysql 5.7.19安装 1.解压文件 [root@centos3 ~]# tar -zxvf mysql-5.7.19-linux-glibc2.12-x86_64.tar.g ...
- Day 6-2简单的socket通信
什么是socket? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面 ...
- 如何在网页中用echarts图表插件做出静态呈现效果
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Map接口----Map中嵌套Map
package cn.good.com; import java.util.HashMap; import java.util.Iterator; import java.util.Map; impo ...