题目大意

  有\(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】插线板 分块的更多相关文章

  1. xcoj 1103 插线板(树链刨分求最大子段和)

    1103: 插线板 时间限制: 1 Sec  内存限制: 128 MB提交: 14  解决: 7 标签提交统计讨论版EditTestData 题目描述 从前有一堆古老的插线板,任意两个插线板之间只有一 ...

  2. poj2636---Electrical Outlets(插线板)

    #include <stdio.h> #include <stdlib.h> int main() { int n,nc,i; scanf("%d",&am ...

  3. NOIWC2018游记

    NOIWC2018游记 接着PKUWC就是NOIWC了.感觉时间很紧呀,但越是紧张呢,就越让人心里觉得充实. 能够去NOIWC,应该是一次非常充实的体验吧. 这一篇游记是接着上一篇写的,时间点上完全都 ...

  4. 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

    前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...

  5. 什么是RAID?RAID有什么用?RAID原理

    什么是RAID 硬盘是个很脆弱的东西,它经常会坏掉.所以,为了保证服务器可靠耐用,硬盘必须时时刻刻保持可用.所以有了RAID这个东西.它的目的是将好几个硬盘合并在一起,就算硬盘坏了一个,剩下还有好几个 ...

  6. Windows Azure HandBook (1) IaaS相关技术

    <Windows Azure Platform 系列文章目录> 1.Microsoft Azure底层是否由System Center和Hyper-V构成? Microsoft Azure ...

  7. XCOJ 1103 (LCA+树链最大子段和)

    题目链接: http://xcacm.hfut.edu.cn/problem.php?id=1103 题目大意:链更新.链查询,求树链的最大子段和.(子段可以为空) 解题思路: 将所有Query离线存 ...

  8. 20145218&20145240 《信息安全系统设计基础》实验一 开发环境的熟悉

    20145218&20145240 <信息安全系统设计基础>实验一 开发环境的熟悉 课程:信息安全系统设计基础 班级:1452 姓名:(按贡献大小排名)刘士嘉 张晓涵 学号:(按贡 ...

  9. 信息安全系统设计基础实验一 20135211&20135216

    北京电子科技学院(BESTI) 实 验 报 告 封面 课程:信息安全系统设计基础              班级:1352           姓名:(按贡献大小排名)李行之 刘蔚然          ...

随机推荐

  1. OO生存指南P1

    写在OO作业之前 在正式写oo作业之前,先说一些“废话”吧,就当是对oo的吐槽. 事实上,早在大一的时候,听说数分很难,然而事实证明数分并没有有让我通宵的体验. 在大二上的时候有一门课叫祭祖,号称是第 ...

  2. itoa()函数和atoi()函数详解

    C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. 以下是用itoa()函数将整数转换为字符串的一个例子:# include <stdio.h># i ...

  3. java中的代码块是什么意思,怎么用

    代码块是一种常见的代码形式.他用大括号“{}”将多行代码封装在一起,形成一个独立的代码区,这就构成了代码块.代码块的格式如下:   方法/步骤     普通代码块:是最常见的代码块,在方法里用一对“{ ...

  4. CRM系统(第四部分)

      阅读目录 1.引入权限组件rbac 2.分配权限 3.登录.引入中间件 1.引入权限组件rbac 1.settings配置app.中间件   INSTALLED_APPS = [ ... ... ...

  5. MySQL 5.7默认ONLY_FULL_GROUP_BY语义介绍

    mysql 5.7版本 出现 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corre ...

  6. Linux 文件特殊权限 SUID SGID SBIT

    文件除了常规的权限r, w, x 还有一些特殊的权限,s与t权限,具体的用处如下 1 SetUID 当s 这个标志出现在文件所有者的x权限上时, 例如/usr/bin/passwd, [root@or ...

  7. idea打包springboot+maven项目并发布在linux上

    2018年11月13日我亲测有效的,很简单的,借鉴博客:https://blog.csdn.net/smilecall/article/details/56288972 第一步:随便建一个maven类 ...

  8. 解决ssh ltt3.bg.cn 'jps' bash: jps: command not found 问题

    >>提君博客原创  http://www.cnblogs.com/tijun/  << linux 上我用hadoop用户配置好SSH后,运行 ssh ltt3.bg.cn ' ...

  9. mysql 清除大数据表单

    背景:mysql数据库中有个日志表记录高达800多万,影响了mysql的正常业务访问,现需要清理三个月之前的所有数据,大概600多万(大概13G) 方法一:传统delete from xxx,传统,普 ...

  10. Delphi (Library Path Browsing Path)

    首先要明白的一个概念是dcu文件 *.dcu是*.pas的编译后单元文件(Delphi Compiled Unit), 编译器把它和库文件连接起来就构成了可执行文件*.exe 或*.dll等,相当于C ...