HNOI 2016 地图
【题目描述】
Hoshizora Rin是个特别好动的少女。
一天Rin来到了一个遥远的都市。这个都市有N个建筑,编号从1到N,其中市中心编号为1,这个都市有M条双向通行的街道,每条街道连接着两个建筑,其中某些街道首尾相连连接成了一个环。Rin通过长时间的走访,已经清楚了这个都市的两个特点:
- 从市中心出发可以到达所有的建筑物。
- 任意一条街道最多存在与一个简单环中。
令Rin心花怒放的是,每个建筑物都会有拉面售卖。拉面有很多不同的种类,但对于Rin而言只有油腻程度的不同,因此我们把油腻程度相同的拉面看做同一种拉面。由于不同建筑物的拉面的油腻程度可能不同,我们用一个正整数来表示拉面的油腻程度。
要知道,拉面可是Rin的最爱,但是现在到了下班高峰期,都市的交通变得非常的堵塞。Rin只能通过没有被堵死的街道通行,去品尝所在建筑物的拉面。
现在Rin想知道,如果她正在编号为x的建筑物,那么在从市中心到x的所有简单路径经过的街道都被堵死的情况下,Rin可以品尝到的拉面中(注意没有出现的拉面是不能算在里面的):
- 油腻程度≤y且品尝次数为奇数次的拉面有多少种?
- 油腻程度≤y且品尝次数为偶数次的拉面有多少种?
【输入格式】
第一行两个正整数N,M,含义如题所示。
第二行一共N个正整数,第i个数Ai表示第i个建筑物出售的拉面的油腻程度。
接下来M行,每行两个正整数x,y,表示在建筑物x,y之间有一条双向通行的街道。数据保证1≤x<y≤N。
接下来一行一个正整数Q,表示询问个数。
接下来Q行每行三个非负整数ty,x,y,x表示询问的建筑物编号,y表示油腻程度的限制,ty=0时表示询问偶数,ty=1表示询问奇数。
【输出格式】
一共Q行,对于每个询问输出一个答案。
【样例输入】
5 6
2 1 6 7 7
1 2
1 3
2 4
4 5
4 5
1 3
3
0 3 2
0 3 1
0 1 7
【样例输出】
0
0
1
【样例解释】
3号建筑物只能到达它自己,而1号建筑物可以到达所有建筑物。
【数据范围】
提示:请注意数据范围中的≤,特殊条件中提到的y均为询问中的y,对于100%的数据,有y≤106。

对仙人掌进行了一遍dfs,得到dfs树
对于每个环,dfs序最小的叫做环的环根
在1到x的简单路径都不能走的限制下,从点x出发,能走到的点记为x的子树
如果x在环上 且 x不是环根,那么x的子树为 dfs序大于x的dfs序 且 不和x在同一个环上的点
如果x在环上 且 x是环根,那么所有dfs序大于x的dfs序的 点 都是x的子树
也就是说,环上点的子树只能累积到环根那里
定义 x的子树大小为son[x],x的dfs序为id[x]
那么对于每一个询问,就是查询 区间[id[x],id[x]+son[x]-1] 内有多少个点的油腻度<=y
用莫队
cnt[k] 表示 油腻度为k的点的个数
对油腻度 也分块 统计
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100001
#define M 150001
using namespace std;
int n,m;
int o[N],oil[N];
int tot,front[N],nxt[M<<],to[M<<];
int dfn[N],low[N],dy[N];
int id[N],son[N];
int siz1,siz2;
int ans[N],tmp,sum[][N],cnt[N*],bl[N];
bool ins[N];
struct node
{
int l,r,ty,lim,num;
}e[N];
void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
}
void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
}
void tarjan(int now,int last)
{
dfn[now]=low[now]=++tot;
dy[tot]=now;
for(int i=front[now];i;i=nxt[i])
{
if(to[i]==last) continue;
if(!dfn[to[i]])
{
tarjan(to[i],now);
low[now]=min(low[now],low[to[i]]);
}
else low[now]=min(low[now],dfn[to[i]]);
}
}
void dfs(int now)
{
ins[now]=true;
id[now]=++tot;
son[now]++;
for(int i=front[now];i;i=nxt[i])
if(!ins[to[i]])
if(low[to[i]]>=dfn[now])
{
dfs(to[i]);
son[now]+=son[to[i]];
}
for(int i=front[now];i;i=nxt[i])
if(!ins[to[i]])
{
dfs(to[i]);
son[dy[low[to[i]]]]+=son[to[i]];
}
}
bool cmp(node p,node q)
{
if(bl[p.l]!=bl[q.l]) return bl[p.l]<bl[q.l];
return p.r<q.r;
}
void up(int pos,bool ty)
{
int p=(oil[pos]-)/siz2+;
if(ty)
{
if(cnt[oil[pos]]&) --sum[][p],++sum[][p];
else if(cnt[oil[pos]]) --sum[][p],++sum[][p];
else ++sum[][p];
++cnt[oil[pos]];
}
else
{
if(cnt[oil[pos]]==) --sum[][p];
else if(cnt[oil[pos]]&) --sum[][p],++sum[][p];
else --sum[][p],++sum[][p];
--cnt[oil[pos]];
}
}
bool cal(int x,bool ty)
{
tmp=;
int last=(x-)/siz2+;
for(int i=;i<last;i++) tmp+=sum[ty][i];
for(int i=(last-)*siz2+;i<=x;i++)
if(cnt[i] && (cnt[i]&)==ty) tmp++;
}
int main()
{
//freopen("map_2016.in","r",stdin);
//freopen("map_2016.out","w",stdout);
read(n); read(m);
siz1=sqrt(n);
for(int i=;i<=n;i++) bl[i]=(i-)/siz1+;
int maxn=;
for(int i=;i<=n;i++) read(o[i]),maxn=max(maxn,o[i]);
siz2=sqrt(maxn);
int u,v;
for(int i=;i<=m;i++) read(u),read(v),add(u,v);
tot=;
tarjan(,);
tot=;
dfs();
for(int i=;i<=n;i++) oil[id[i]]=o[i];
int q,x;
read(q);
for(int i=;i<=q;i++)
{
read(e[i].ty);
read(x);
e[i].l=id[x];
e[i].r=id[x]+son[x]-;
read(e[i].lim);
e[i].num=i;
}
sort(e+,e+q+,cmp);
int L=,R=;
for(int i=;i<=q;++i)
{
while(R<e[i].r) up(++R,true);
while(L>e[i].l) up(--L,true);
while(R>e[i].r) up(R--,false);
while(L<e[i].l) up(L++,false);
cal(e[i].lim,e[i].ty);
ans[e[i].num]=tmp;
}
for(int i=;i<=q;i++) printf("%d\n",ans[i]);
}
HNOI 2016 地图的更多相关文章
- [HNOI 2016]树
Description 题库链接 给你一棵 \(N\) 个节点根节点为 \(1\) 的有根树,结点的编号为 \(1\sim N\) :我们称这颗树为模板树.需要通过这棵模板树来构建一颗大树.构建过程如 ...
- 【BZOJ 4539】【HNOI 2016】树
http://www.lydsy.com/JudgeOnline/problem.php?id=4539 今天测试唯一会做的一道题. 按题目要求,如果暴力的把模板树往大树上仍,最后得到的大树是$O(n ...
- hnoi 2016 省选总结
感觉省选好难的说...反正我数据结构太垃圾正解想到了也打不出来打一打暴力就滚粗了! DAY1 0+20+30 DAY2 60-20+0+60 最后170-20分,暴力分还是没有拿全! 然而这次是给了5 ...
- HNOI 2016 省队集训日记
第一天 DeepDarkFantasy 从东京出发,不久便到一处驿站,写道:日暮里. ——鲁迅<藤野先生> 定义一个置换的平方为对1~n的序列做两次该置换得到的序列.已知一个置换的平方, ...
- 数据结构(树链剖分,堆):HNOI 2016 network
2215. [HNOI2016]网络 ★★★☆ 输入文件:network_tenderRun.in 输出文件:network_tenderRun.out 简单对比时间限制:2 s 内存 ...
- [HNOI 2016]最小公倍数
Description 题库链接 给定一张 \(N\) 个顶点 \(M\) 条边的无向图(顶点编号为 \(1,2,\cdots,n\) ),每条边上带有权值.所有权值都可以分解成 \(2^a\time ...
- [HNOI 2016]序列
Description 题库链接 给你一个长度为 \(n\) 的序列 \(A\) ,给出 \(q\) 组询问.每次询问 \([l,r]\) ,求该区间内所有的子序列中最小值的和. \(1\leq n, ...
- [HNOI 2016]大数
Description 题库链接 给你一个长度为 \(n\) ,可含前导零的大数,以及一个质数 \(p\) . \(m\) 次询问,每次询问你一个大数的子区间 \([l,r]\) ,求出子区间中有多少 ...
- [HNOI 2016]网络
Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做 一条树边.两个服务器进行数据的交互时,数据会经过连接这两个服务器的路径上的所有 ...
随机推荐
- Tic-Tac-Toe
Description Kim likes to play Tic-Tac-Toe. Given a current state, and now Kim is going to take his n ...
- Phpcms V9导航循环下拉菜单的调用技巧
这个方法基于PC V9官方模版中的调用方法,然后利用后台的“Phpcms V9菜单是否显示设置”控制菜单是否显示出来. 先看看最后的效果: 调用方法: <div id="navbar& ...
- C语言 结构体相关 函数 指针 数组
. 作者 : 万境绝尘 转载请注明出处 : http://www.hanshuliang.com/?post=30 . 结构体概述 : 结构体是 多个 变量的集合, 变量的类型可以不同; -- 可进行 ...
- Java微笔记(2)
Java 中方法的重载 一,如果同一个类中包含了两个或两个以上方法名相同.方法参数的个数.顺序或类型不同的方法,则称为方法的重载,也可称该方法被重载了 二,.判断方法重载的依据: 1. 必须是在同一个 ...
- ACM 第九天
动态规划1 动态规划问题是面试题中的热门话题,如果要求一个问题的最优解(通常是最大值或者最小值),而且该问题能够分解成若干个子问题,并且小问题之间也存在重叠的子问题,则考虑采用动态规划. 1.LLS ...
- 《剑指offer》---两个栈实现队列
本文算法使用python3实现 1.题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 时间限制:1s:空间限制:32768K 2.思路描述: ...
- lintcode-197-排列序号
197-排列序号 给出一个不含重复数字的排列,求这些数字的所有排列按字典序排序后该排列的编号.其中,编号从1开始. 样例 例如,排列 [1,2,4] 是第 1 个排列. 思路 参考http://www ...
- .net平台借助第三方推送服务在推送Android,IOS消息(极光推送_V3版本)最新
最近刚从极光推送官网上看到V2版本要停用,不得不有重新写V3版本的.这里用到了 HTTP Basic Authentication http://www.cnblogs.com/pingming/p/ ...
- Qt自定义标题栏
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt自定义标题栏 本文地址:http://techieliang.com/2017/1 ...
- intellij idea 如何将一个普通项目转换为maven项目
1.工程文件下新建文件pom.xml,并填写好内容. 2.在pom.xml 文件上右键 Add as Maven Project.