loj2062 [HAOI2016]地图

Posted poorpool

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了loj2062 [HAOI2016]地图相关的知识,希望对你有一定的参考价值。

ref

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n, m, q, a[100005], uu, vv, hea[100005], cnt, dfn[100005], loo[100005];
int idx, dui[100005], qwq[100005], siz[100005], ans[100005], blc1, blc2;
int bei[100005], jis[1000005], qaq[2][1005], ovo[100005];
struct Edge{
    int too, nxt, val;
}edge[300005];
struct Node{
    int ll, rr, id, ty, li;
}nd[100005];
void add_edge(int fro, int too){
    edge[++cnt].nxt = hea[fro];
    edge[cnt].too = too;
    hea[fro] = cnt;
}
bool cmp(Node x, Node y){
    if(bei[x.ll]!=bei[y.ll])    return bei[x.ll]<bei[y.ll];
    if(bei[x.ll]&1) return x.rr<y.rr;
    else    return x.rr>y.rr;
}
void dfs1(int x, int f){
    dfn[x] = loo[x] = ++idx;
    dui[idx] = x;
    for(int i=hea[x]; i; i=edge[i].nxt){
        int t=edge[i].too;
        if(t==f)    continue;
        if(!dfn[t]){
            dfs1(t, x);
            loo[x] = min(loo[x], loo[t]);
        }
        else    loo[x] = min(loo[x], dfn[t]);
    }
}
void dfs2(int x){
    qwq[x] = ++idx;
    siz[x] = 1;
    for(int i=hea[x]; i; i=edge[i].nxt){
        int t=edge[i].too;
        if(!qwq[t] && loo[t]>=dfn[x]){
            dfs2(t);
            siz[x] += siz[t];
        }
    }
    for(int i=hea[x]; i; i=edge[i].nxt){
        int t=edge[i].too;
        if(!qwq[t] && loo[t]<dfn[x]){
            dfs2(t);
            siz[dui[loo[t]]] += siz[t];
        }
    }
}
void add(int x){
    int p=(x-1)/blc2+1;
    if(jis[x]&1)    qaq[1][p]--, qaq[0][p]++;
    else if(jis[x]) qaq[0][p]--, qaq[1][p]++;
    else    qaq[1][p]++;
    jis[x]++;
}
void dec(int x){
    int p=(x-1)/blc2+1;
    if(jis[x]==1)   qaq[1][p]--;
    else if(jis[x]&1)   qaq[1][p]--, qaq[0][p]++;
    else    qaq[0][p]--, qaq[1][p]++;
    jis[x]--;
}
int main(){
    cin>>n>>m;
    blc1 = sqrt(n);
    blc2 = sqrt(1000000);
    for(int i=1; i<=n; i++){
        scanf("%d", &a[i]);
        bei[i] = (i - 1) / blc1 + 1;
    }
    for(int i=1; i<=m; i++){
        scanf("%d %d", &uu, &vv);
        add_edge(uu, vv);
        add_edge(vv, uu);
    }
    dfs1(1, 0);
    idx = 0;
    dfs2(1);
    cin>>q;
    for(int i=1; i<=q; i++){
        scanf("%d %d %d", &nd[i].ty, &uu, &nd[i].li);
        nd[i].ll = qwq[uu]; nd[i].rr = qwq[uu] + siz[uu] - 1;
        nd[i].id = i;
    }
    sort(nd+1, nd+1+q, cmp);
    for(int i=1; i<=n; i++)
        ovo[qwq[i]] = a[i];
    int l=nd[1].ll, r=l-1;
    for(int i=1; i<=q; i++){
        while(l>nd[i].ll)   add(ovo[--l]);
        while(l<nd[i].ll)   dec(ovo[l++]);
        while(r<nd[i].rr)   add(ovo[++r]);
        while(r>nd[i].rr)   dec(ovo[r--]);
        int now=0, p=(nd[i].li-1)/blc2+1;
        for(int j=1; j<p; j++)
            now += qaq[nd[i].ty][j];
        for(int j=blc2*(p-1)+1; j<=nd[i].li; j++)
            if(jis[j] && (jis[j]&1)==nd[i].ty)
                now++;
        ans[nd[i].id] = now;
    }
    for(int i=1; i<=q; i++)
        printf("%d\n", ans[i]);
    return 0;
}

以上是关于loj2062 [HAOI2016]地图的主要内容,如果未能解决你的问题,请参考以下文章

loj10139. 「一本通 4.5 练习 1」树上操作(loj2125. 「HAOI2015」树上操作 )

HAOI2016找相同字符

loj2278. 「HAOI2017」字符串

[LOJ][HAOI2017]供给侧改革

LOJ#2127. 「HAOI2015」按位或

loj#2312. 「HAOI2017」八纵八横(线性基 线段树分治)