分析

树上莫队裸题。
好博客

树剖的时候不能再次dfs重儿子。(好像是废话,但我因为这个问题调了三小时)

代码

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x){
    T data=0;
    int w=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=10*data+ch-'0',ch=getchar();
    return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;

const int MAXN=1e5+7;
int n,q;
map<int,int>M;
int a[MAXN],id;
int belong[MAXN],block;

struct Edge
{
    int nx,to;
}E[MAXN<<2];
int head[MAXN],ecnt;

void addedge(int x,int y)
{
    E[++ecnt].to=y;
    E[ecnt].nx=head[x],head[x]=ecnt;
}

int fa[MAXN],dep[MAXN],sz[MAXN],son[MAXN],top[MAXN];
int st[MAXN],ed[MAXN],pot[MAXN],clk;

void dfs1(int x,int f)
{
    fa[x]=f,sz[x]=1;
    st[x]=++clk,pot[clk]=x;
    dep[x]=dep[f]+1;
    for(int i=head[x];i;i=E[i].nx)
    {
        int y=E[i].to;
        if(y==f)
            continue;
        dfs1(y,x);
        sz[x]+=sz[y];
        if(sz[y]>sz[son[x]])
            son[x]=y;
    }
    ed[x]=++clk,pot[clk]=x;
}

void dfs2(int x,int topf)
{
    top[x]=topf;
    if(!son[x])
        return;
    dfs2(son[x],topf);
    for(int i=head[x];i;i=E[i].nx)
    {
        int y=E[i].to;
        if(y==fa[x]||y==son[x]) // edit 1:cannot dfs son[x] twice and wrongly
            continue;
        dfs2(y,y);
    }
}

int lca(int x,int y)
{
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]])
            swap(x,y);
        x=fa[top[x]];
    }
    return dep[x]<dep[y]?x:y;
}

struct Quiz
{
    int l,r,f,id;
    bool operator<(const Quiz&x)
    {
        if(belong[l]^belong[x.l])
            return l<x.l;
        else
            return r<x.r;
    }
}Q[MAXN];

int ql,qr,res;
bool used[MAXN];
int cnt[MAXN],ans[MAXN];

void add(int x)
{
    if(++cnt[x]==1)
        ++res;
}

void del(int x)
{
    if(--cnt[x]==0)
        --res;
}

void change(int x)
{
    used[x]?del(a[x]):add(a[x]);
    used[x]^=1;
}

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(n);read(q);
    block=sqrt(n);
    for(int i=1;i<=n;++i)
    {
        read(a[i]);
        if(!M[a[i]])
            M[a[i]]=++id;
        a[i]=M[a[i]];
    }
    for(int i=1;i<=2*n;++i) // edit 1:belong should be inited to 2n
        belong[i]=(i-1)/block+1;
    for(int i=1;i<n;++i)
    {
        int x,y;
        read(x);read(y);
        addedge(x,y);
        addedge(y,x);
    }
    dfs1(1,0);
    dfs2(1,1);
    for(int i=1;i<=q;++i)
    {
        int x,y;
        read(x);read(y);
        if(st[x]>st[y])
            swap(x,y);
        int f=lca(x,y);
        if(f==x)
            Q[i].l=st[x],Q[i].r=st[y];
        else
            Q[i].l=ed[x],Q[i].r=st[y],Q[i].f=f;
        Q[i].id=i;
    }
    sort(Q+1,Q+q+1);
    ql=1,qr=0,res=0;
    for(int i=1;i<=q;++i)
    {
        while(ql>Q[i].l)
            change(pot[--ql]);
        while(qr<Q[i].r)
            change(pot[++qr]);
        while(ql<Q[i].l)
            change(pot[ql++]);
        while(qr>Q[i].r)
            change(pot[qr--]);
        if(Q[i].f)
            change(Q[i].f);
        ans[Q[i].id]=res;
        if(Q[i].f)
            change(Q[i].f);
    }
    for(int i=1;i<=q;++i)
        printf("%d\n",ans[i]);
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

SPOJCOT2 Count on a tree II的更多相关文章

  1. SPOJcot2 Count on a tree II (树上莫队)

    You are given a tree with N nodes. The tree nodes are numbered from 1 to N. Each node has an integer ...

  2. 【SPOJ10707】 COT2 Count on a tree II

    SPOJ10707 COT2 Count on a tree II Solution 我会强制在线版本! Solution戳这里 代码实现 #include<stdio.h> #inclu ...

  3. 【BZOJ2589】 Spoj 10707 Count on a tree II

    BZOJ2589 Spoj 10707 Count on a tree II Solution 吐槽:这道题目简直...丧心病狂 如果没有强制在线不就是树上莫队入门题? 如果加了强制在线怎么做? 考虑 ...

  4. 【BZOJ2589】[SPOJ10707]Count on a tree II

    [BZOJ2589][SPOJ10707]Count on a tree II 题面 bzoj 题解 这题如果不强制在线就是一个很\(sb\)的莫队了,但是它强制在线啊\(qaq\) 所以我们就用到了 ...

  5. 【SPOJ】Count On A Tree II(树上莫队)

    [SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...

  6. spoj COT2 - Count on a tree II

    COT2 - Count on a tree II http://www.spoj.com/problems/COT2/ #tree You are given a tree with N nodes ...

  7. AC日记——Count on a tree II spoj

    Count on a tree II 思路: 树上莫队: 先分块,然后,就好办了: 来,上代码: #include <cmath> #include <cstdio> #inc ...

  8. SPOJ COT2 - Count on a tree II(LCA+离散化+树上莫队)

    COT2 - Count on a tree II #tree You are given a tree with N nodes. The tree nodes are numbered from  ...

  9. COT2 - Count on a tree II(树上莫队)

    COT2 - Count on a tree II You are given a tree with N nodes. The tree nodes are numbered from 1 to N ...

随机推荐

  1. spring boot 2.0 + 静态资源被拦截,怎么办?

    问题描述:使用springboot 2.0后,按照springboot 1.5版本(以下简称旧版)的方式去配置项目.结果发现静态资源访问不到了,本文对此情况分析.处理 项目结构: 直接上图 如果是在旧 ...

  2. WPF几种高级绑定

    (1)Binding  + RelativeSource + AncestorType 模式  , 根据关联源所指定的类型,可动态绑定指定类型的Path属性(Path可以省略)(PS:动态指父级在运行 ...

  3. English trip -- VC(情景课)5 C It's on Main Street 在主街上

    Grammar focus 语法点: on,   在...上 next to ,   旁边,周围 aross from ,  对面 between  在...之间 in front of  在…前面 ...

  4. Almost Acyclic Graph CodeForces - 915D (思维,图论)

    大意: 给定无向图, 求是否能删除一条边后使图无环 直接枚举边判环复杂度过大, 实际上删除一条边可以看做将该边从一个顶点上拿开, 直接枚举顶点即可 复杂度$O(n(n+m))$ #include &l ...

  5. 『PyTorch』第九弹_前馈网络简化写法

    『PyTorch』第四弹_通过LeNet初识pytorch神经网络_上 『PyTorch』第四弹_通过LeNet初识pytorch神经网络_下 在前面的例子中,基本上都是将每一层的输出直接作为下一层的 ...

  6. hdu3374 kmp+最小表示法

    Give you a string with length N, you can generate N strings by left shifts. For example let consider ...

  7. python-day47--pymysql模块

    一.安装导入 #安装 pip3 install pymysql 二.使用 1 .基本使用 import pymysql # 链接,拿到游标 conn=pymysql.connect(host='loc ...

  8. HDU-3790 最短路径问题(双重权值)

    Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的.   Inp ...

  9. dp练习(10)——拦截导弹

    1044 拦截导弹 1999年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Descripti ...

  10. laravel中通过查询构造器,实现数据的curd

    //查询构造器: public function query1(){ //利用查询构造器,插入数据: /*$num=DB::table('student')->insert( ['name'=& ...