当前位置: 首页 > 工具软件 > Haruna > 使用案例 >

[BZOJ 4129]Haruna’s Breakfast

李凯定
2023-12-01

。。OTZ终于写过了

树上待修改莫队

错误点大概有三个

1.p和q搞混了,以后不要用这两个变量

2.size[u] += size[v]不知道什么时候被吃掉了

3.B = sqrt(n) + 1




#include 
   
   
    
    

using namespace std;
#define maxn 100010

int P[maxn];
int c[maxn];
bool is[maxn];
struct Block{
    int vis[1000], sum, cnt, l, r, wy;
    void build(int l, int r){
        this->l = l, this->r = r;
        wy = l-1;
        sum = r - l + 1;
    }
    void update(int u){
        int t = c[u] - wy;
        if(!is[u]){
            vis[t] --;
            if(vis[t] == 0)cnt --;
        }
        else{
            if(vis[t] == 0)cnt ++;
            vis[t] ++;
        }
    }
    bool empty(){return sum == cnt;}
    int ask(){
        for(int i = 1; i <= sum; i ++)
            if(!vis[i])return i + wy;
    }
}blo[1000];

int n, m;
struct Edge{
    int to, next;
}edge[maxn << 1];

int h[maxn], cnt;
void add(int u, int v){
    cnt ++;
    edge[cnt].to = v;
    edge[cnt].next = h[u];
    h[u] = cnt;
}

int dfn[maxn], dfs_clock, pos[maxn];

struct opt{
    int u, v, id, t;
    bool operator<(const opt& k)const{
        if(pos[u] != pos[k.u])return dfn[u] < dfn[k.u];
        if(pos[v] != pos[k.v])return dfn[v] < dfn[k.v];
        return t < k.t;
    }
}q[maxn], p[maxn];
int qnt, pnt;

const int root = 1;


int fa[maxn], dep[maxn], B, tim, size[maxn];
stack
    
    
     
     S;
void dfs(int u){
    dfn[u] = ++ dfs_clock;
    dep[u] = dep[fa[u]] + 1;
    S.push(u);
    for(int i = h[u]; i; i = edge[i].next){
        int v = edge[i].to;
        if(v == fa[u])continue;
        fa[v] = u;
        dfs(v);
        size[u] += size[v];
        if(size[u] >= B){
            ++ tim;
            for(;;){
                v = S.top();
                if(v == u)break;
                pos[v] = tim;
                S.pop();
            }
            size[u] = 0;
        }
    }size[u] ++;
}
int anc[maxn][20];
void pre_LCA(){
    memset(anc, -1, sizeof anc);
    for(int i = 1; i <= n; i ++)
        anc[i][0] = fa[i];
    for(int j = 1; 1<
     
     
      
      <= n; j ++){
        for(int i = 1; i <= n; i ++){
            int a = anc[i][j-1];
            if(~a)anc[i][j] = anc[a][j-1];
        }
    }
}
#define log Log
int log;
int ask_LCA(int p, int q){
    if(dep[p] < dep[q])swap(p, q);
    for(log = 1; 1<
      
      
       
       <= dep[p]; log ++);log --;
    for(int i = log; i >= 0; i --)
        if(~anc[p][i] && dep[anc[p][i]] >= dep[q])
            p = anc[p][i];
    if(p == q)return p;
    for(int i = log; i >= 0; i --)
        if(~anc[p][i] && anc[p][i] != anc[q][i])
            p = anc[p][i], q = anc[q][i];
    return fa[p];
}

int ans[maxn], last[maxn], pre[maxn];

void Xor(int u){
    is[u] ^= 1;
    if(c[u] > n)return;
    blo[P[c[u]]].update(u);
}

void Move(int u, int v){
    while(u != v){
        if(dep[u] < dep[v])swap(u, v);
        Xor(u); u = fa[u];
    }
}

int ask(){
    for(int i = 1; i <= B; i ++)
        if(!blo[i].empty())
            return blo[i].ask();
}

void Modify(int u, int v){
    if(is[u]){
        Xor(u);
        c[u] = v;
        Xor(u);
        return;
    }
    c[u] = v;
}

int main(){
    scanf("%d%d", &n, &m);
    B = sqrt(n) + 1;
    for(int i = 1; i <= n; i ++)
        scanf("%d", &c[i]);
    int u, v, d;
    for(int i = 1; i < n; i ++){
        scanf("%d%d", &u, &v);
        add(u, v), add(v, u);
    }
    dfs(root); ++ tim;
    for(;!S.empty(); S.pop())pos[S.top()] = tim;
    pre_LCA();
    for(int i = 1; i <= m; i ++){
        scanf("%d%d%d", &d, &u, &v);
        if(!d){
            ++ pnt;
            p[pnt].u = u;
            p[pnt].v = v;
            p[pnt].t = pnt;
        }
        else{
            ++ qnt;
            q[qnt].u = u;
            q[qnt].v = v;
            q[qnt].id = qnt;
            q[qnt].t = pnt;
        }
    }

    for(int i = 1; i <= B; i ++){
        int L = (i-1) * B + 1, R = i * B;
        R = min(R, n);
        if(i == 1)L = 0;
        for(int j = L; j <= R; j ++)
            P[j] = i;
        blo[i].build(L, R);
        if(R == n){
            B = i;
            break;
        }
    }

    for(int i = 1; i <= n; i ++)
        last[i] = c[i];
    for(int i = 1; i <= pnt; i ++){
        pre[i] = last[p[i].u];
        last[p[i].u] = p[i].v;
    }

    sort(q+1, q+1+qnt);
    int l = 1, r = 1, t = 0, LCA;
    for(int i = 1; i <= qnt; i ++){
        while(t < q[i].t)t ++, Modify(p[t].u, p[t].v);
        while(t > q[i].t)Modify(p[t].u, pre[t]), t --;
        Move(l, q[i].u), Move(r, q[i].v);
        l = q[i].u, r = q[i].v;
        LCA = ask_LCA(l, r);
        Xor(LCA);
        ans[q[i].id] = ask();
        Xor(LCA);
    }

    for(int i = 1; i <= qnt; i ++)
        printf("%d\n", ans[i]);

    return 0;
}

      
      
     
     
    
    
   
   

 类似资料:

相关阅读

相关文章

相关问答