【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 姓名:(按贡献大小排名)李行之 刘蔚然 ...
随机推荐
- 自定义分页及Cookie、Session机制
分页 自定义分页 data = [] , ): tmp = {"id": i, "name": "alex-{}".format(i)} d ...
- VMware vSphere 6 序列号
vSphere 6 Hypervisor HY0XH-D508H-081U8-JA2GH-CCUM2 4C4WK-8KH8L-H85J0-UHCNK-8CKQ8 NV09R-2W007-08D38-C ...
- Nginx 通过 Lua + Redis 实现动态封禁 IP
一.背景 为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单.对于黑名单之内的 IP ,拒绝提供服务. 二.架构 实现 IP 黑名单的功能有很多途径: 1.在操作系统层面 ...
- c++ 入门之深入探讨拷贝函数和内存分配
在c++入门之深入探讨类的一些行为时,说明了拷贝函数即复制构造函数运用于如下场景: 对象作为函数的参数,以值传递的方式传给函数. 对象作为函数的返回值,以值的方式从函数返回 使用一个对象给另一个对象初 ...
- c++入门之 深入cin
cin 表示输入流,但是究其本质,又能认识到什么呢?先上代码: #include "iostream" };//c++11中使用{}进行重新命名 int main() { usin ...
- IBM的淘汰之路
BM曾经在计算领域独领风骚,但是90年被PC产业链上的微软.英特尔等厂商围殴,遭遇最严重的危机; 今天在云计算市场,IBM曾在遭遇同样的危机,这一次不知道它能否安然度过; IBM收购红帽转向混合云,是 ...
- elasticsearch聚合操作——本质就是针对搜索后的结果使用桶bucket(允许嵌套)进行group by,统计下分组结果,包括min/max/avg
分析 Elasticsearch有一个功能叫做聚合(aggregations),它允许你在数据上生成复杂的分析统计.它很像SQL中的GROUP BY但是功能更强大. 举个例子,让我们找到所有职员中最大 ...
- Django 中的Form、ModelForm
一.ModelForm 源码 class ModelForm(BaseModelForm, metaclass=ModelFormMetaclass): pass def modelform_fact ...
- 《梦断代码》Scott Rosenberg著(二)
书中有一段说的是一个闪烁缺陷——在改变某软件中某个窗体的尺寸时,屏幕会闪烁一秒钟左右.虽然该缺陷不会影响程序运行,但它不符合作者的审美观,历时六个多月仍然没能修正.其实在日常的编程中也有许多小bug的 ...
- 3proxy使用方法
转自:DRL@fireinice写的教程 ******************************************************************************* ...