【题目描述】

Hoshizora Rin是个特别好动的少女。

一天Rin来到了一个遥远的都市。这个都市有N个建筑,编号从1到N,其中市中心编号为1,这个都市有M条双向通行的街道,每条街道连接着两个建筑,其中某些街道首尾相连连接成了一个环。Rin通过长时间的走访,已经清楚了这个都市的两个特点:

  1. 从市中心出发可以到达所有的建筑物。
  2. 任意一条街道最多存在与一个简单环中。

令Rin心花怒放的是,每个建筑物都会有拉面售卖。拉面有很多不同的种类,但对于Rin而言只有油腻程度的不同,因此我们把油腻程度相同的拉面看做同一种拉面。由于不同建筑物的拉面的油腻程度可能不同,我们用一个正整数来表示拉面的油腻程度。

要知道,拉面可是Rin的最爱,但是现在到了下班高峰期,都市的交通变得非常的堵塞。Rin只能通过没有被堵死的街道通行,去品尝所在建筑物的拉面。

现在Rin想知道,如果她正在编号为x的建筑物,那么在从市中心到x的所有简单路径经过的街道都被堵死的情况下,Rin可以品尝到的拉面中(注意没有出现的拉面是不能算在里面的):

  1. 油腻程度≤y且品尝次数为奇数次的拉面有多少种?
  2. 油腻程度≤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 地图的更多相关文章

  1. [HNOI 2016]树

    Description 题库链接 给你一棵 \(N\) 个节点根节点为 \(1\) 的有根树,结点的编号为 \(1\sim N\) :我们称这颗树为模板树.需要通过这棵模板树来构建一颗大树.构建过程如 ...

  2. 【BZOJ 4539】【HNOI 2016】树

    http://www.lydsy.com/JudgeOnline/problem.php?id=4539 今天测试唯一会做的一道题. 按题目要求,如果暴力的把模板树往大树上仍,最后得到的大树是$O(n ...

  3. hnoi 2016 省选总结

    感觉省选好难的说...反正我数据结构太垃圾正解想到了也打不出来打一打暴力就滚粗了! DAY1 0+20+30 DAY2 60-20+0+60 最后170-20分,暴力分还是没有拿全! 然而这次是给了5 ...

  4. HNOI 2016 省队集训日记

    第一天 DeepDarkFantasy 从东京出发,不久便到一处驿站,写道:日暮里.  ——鲁迅<藤野先生> 定义一个置换的平方为对1~n的序列做两次该置换得到的序列.已知一个置换的平方, ...

  5. 数据结构(树链剖分,堆):HNOI 2016 network

    2215. [HNOI2016]网络 ★★★☆   输入文件:network_tenderRun.in   输出文件:network_tenderRun.out   简单对比时间限制:2 s   内存 ...

  6. [HNOI 2016]最小公倍数

    Description 题库链接 给定一张 \(N\) 个顶点 \(M\) 条边的无向图(顶点编号为 \(1,2,\cdots,n\) ),每条边上带有权值.所有权值都可以分解成 \(2^a\time ...

  7. [HNOI 2016]序列

    Description 题库链接 给你一个长度为 \(n\) 的序列 \(A\) ,给出 \(q\) 组询问.每次询问 \([l,r]\) ,求该区间内所有的子序列中最小值的和. \(1\leq n, ...

  8. [HNOI 2016]大数

    Description 题库链接 给你一个长度为 \(n\) ,可含前导零的大数,以及一个质数 \(p\) . \(m\) 次询问,每次询问你一个大数的子区间 \([l,r]\) ,求出子区间中有多少 ...

  9. [HNOI 2016]网络

    Description 一个简单的网络系统可以被描述成一棵无根树.每个节点为一个服务器.连接服务器与服务器的数据线则看做 一条树边.两个服务器进行数据的交互时,数据会经过连接这两个服务器的路径上的所有 ...

随机推荐

  1. POJ 1755 Triathlon(线性规划の半平面交)

    Description Triathlon is an athletic contest consisting of three consecutive sections that should be ...

  2. Java学习个人备忘录之抽象类

    抽象类 特点:1. 方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰,抽象方法必须定义在抽象类中.该类必须也被abstract修饰2. 抽象类不可以被实例化. 为什么?  因为调 ...

  3. Uva 1600 Patrol Robot (BFS 最短路)

    这道题运用的知识点是求最短路的算法.一种方法是利用BFS来求最短路. 需要注意的是,我们要用一个三维数组来表示此状态是否访问过,而不是三维数组.因为相同的坐标可以通过不同的穿墙方式到达. #inclu ...

  4. Coursera-Note: Internet History, Technology and Secure (1st week to 9th week)

    目录 Coursera-Note: Internet History, Technology and Secure 第一周 第二周 数据交换: Packet switching技术: 第三周 创造ht ...

  5. java的参数传递

    1按值传递:传递的是原始值的副本,而不是原始值的内存地址 基本数据类型是传原始值的副本 class Test02 { public static void main(String[] args) { ...

  6. 【EF】Entity Framework 6新特性:全局性地自定义Code First约定

    应用场景 场景一:EF Code First默认使用类名作为表名,如果我们需要给表名加个前缀,例如将类名Category映射到表Shop_Category.将Product映射到Shop_Produc ...

  7. 【bzoj4698】[Sdoi2008] Sandy的卡片 后缀数组

    题目描述 Sandy和Sue的热衷于收集干脆面中的卡片.然而,Sue收集卡片是因为卡片上漂亮的人物形象,而Sandy则是为了积攒卡片兑换超炫的人物模型.每一张卡片都由一些数字进行标记,第i张卡片的序列 ...

  8. Django 2.0 学习(05):Django Admin

    Django Admin 站点的管理者,而非访问者. 创建admin用户 首先,执行下面命令: python manage.py createsuperuser 其次,输入用户名和密码: Userna ...

  9. SP263 PERIOD - Period

    题目描述 For each prefix of a given string S with N characters (each character has an ASCII code between ...

  10. eval以及时间操作

    1.  在Python里面 val=eval(“1+1”) 只能执行简单的表达式,不能执行有逻辑性的代码.并且能拿到返回值.可以执行字符串的计算: exec() 执行代码: 在JS里面:eval可以实 ...