BZOJ 4564: [Haoi2016]地图

题目大意

原题链接

给一个仙人掌,每个结点有一个权值,查询每个仙人掌的子树(算本身)(子树结点满足:必须经过该点才能到达跟,即该点是子树的割点)有多少种小于y的权值个数为奇数(或偶数)。y是每次询问时候给。
可离线,1e5个点和询问

算法分析

如果在树上那就需要用DFS序,仙人掌也有DFS序,叫做仙人掌序列嘛。
实际上就是需要先预处理出一个结点在环上的相邻结点(有一个一定是DFS的父亲结点),最后走环上的那个结点并且不算当前结点的子树。

查询就变成了区间查询,用3809的那种莫队+分块。

注意

1、我这个SB每次块都忘了初始化,所以一定要测试极限数据啊。
2、注意考虑0结点,数据中y和w都有=0的情况。
3、为了在第二次DFS的时候用vis数组记录即可,当做图的便利,否则判断挺麻烦的。

/*
维护部分:
一个支持初始化,修改,奇偶查询的分块
一段莫队算法 
根据仙人掌序列得到需要被维护的序列
根据询问进行转换 

仙人掌部分:
第一次DFS得到fa和son
第二次DFS得到仙人掌序列 
*/
#include<cmath>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+105,maxm=15e4+105,maxs=1e6+105;
int tl[maxn],tr[maxn],a[maxn];
namespace Captain_Mo
{
    static const int Tim=500,n=1e6;
    int N,Q,ans[maxn],belong[maxs];
    struct data{
        int l,r,b,op,id;
        friend bool operator<(data a,data b)
        {
            return belong[a.l]!=belong[b.l]?belong[a.l]<belong[b.l]:a.r<b.r;
        }
    }q[maxn];
    struct block
    {
        int num,L[maxs/Tim+5],R[maxs/Tim+5],vis[maxs],ji[maxs/Tim+5],ou[maxs/Tim+5];
        void Build()
        {
            L[0]=R[
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值