不懂就问
  • 板块学术版
  • 楼主Ame__
  • 当前回复1
  • 已保存回复1
  • 发布时间2020/9/21 09:26
  • 上次更新2023/11/5 12:51:13
查看原帖
不懂就问
245875
Ame__楼主2020/9/21 09:26

对于此代码,多组询问的时候要新建线段树,我用的指针但是删内存的方法好像不太对(,到底应该怎么删内存?

#include<bits/stdc++.h>
    
#define LL long long
    
#define _ 0
    
using namespace std;
    
/*Grievous Lady*/
    
const int BUF_SIZE = 1 << 12;
    
char buf[BUF_SIZE] , *buf_s = buf , *buf_t = buf + 1;
    
#define PTR_NEXT() \
{ \
    buf_s ++; \
    if(buf_s == buf_t) \
    { \
        buf_s = buf; \
        buf_t = buf + fread(buf , 1 , BUF_SIZE , stdin); \
    } \
}
    
template <typename _m_> void mian(_m_ & _n_){
    int _x_ = 0 , _nega_ = 0;
    while(*buf_s != '-' && !isdigit(*buf_s)) PTR_NEXT(); if(*buf_s == '-'){_nega_ = 1; PTR_NEXT();}
    while(isdigit(*buf_s)){_x_ = _x_ * 10 + *buf_s - '0'; PTR_NEXT();} if(_nega_) _x_ = -_x_; (_n_) = (_x_);
}
    
template <typename _n_> bool cmax(_n_ &a , const _n_ &b){ return a < b ? a = b , 1 : 0; }
    
template <typename _n_> bool cmin(_n_ &a , const _n_ &b){ return a > b ? a = b , 1 : 0; }
    
const int kato = 1e5 + 1;

int t , n , m , opt , x , y , z , a[kato];

struct SGT{
    protected:

        struct Edge{
            int to;
            Edge *nxt;
            Edge(int to , Edge *nxt): to(to) , nxt(nxt) {}
        }*head[kato];

        struct node{
            node *ch[2];
            int l , r;
            int col[101];
            node(int l = 0 , int r = 0): l(l) , r(r){
                ch[0] = ch[1] = NULL;
                memset(col , 0 , sizeof(col));
            }
            inline int mid(){
                return (l + r) >> 1;
            }
            inline void up(){
                for(int i = 1;i <= 100;i ++){
                    col[i] = ch[0] -> col[i] + ch[1] -> col[i];
                }
            }
        }*root;

        int cnt , fa[kato] , dfn[kato] , top[kato] , son[kato] , size[kato] , dep[kato] , id[kato];

        void dfs1(int u , int f){
            fa[u] = f; size[u] = 1;
            dep[u] = dep[f] + 1;
            for(Edge *i = head[u] ; i ; i = i -> nxt){
                int v = i -> to;
                if(v == f) continue;
                dfs1(v , u);
                size[u] += size[v];
                if(!son[u] || size[v] > size[son[u]]) son[u] = v;
            }
        }

        void dfs2(int u , int f){
            top[u] = f , dfn[u] = ++ cnt;
            id[cnt] = u;
            if(son[u]) dfs2(son[u] , f);
            for(Edge *i = head[u] ; i ; i = i -> nxt){
                int v = i -> to;
                if(!dfn[v]) dfs2(v , v);
            }
        }

        inline void build(node *&o , int l , int r){
            o = new node(l , r);
            if(l == r){
                o -> col[a[id[l]]] = 1;
                return;
            }
            build(o -> ch[0] , l , o -> mid()); build(o -> ch[1] , o -> mid() + 1 , r);
            o -> up();
        }

        inline void Modify(node *o , int l , int r , int val){
            if(l <= o -> l && o -> r <= r){
                o -> col[a[id[l]]] = 0;
                a[id[l]] = val;
                o -> col[a[id[l]]] = 1;
                return;
            }
            if(l <= o -> mid()){
                Modify(o -> ch[0] , l , r , val);
            }
            if(r > o -> mid()){
                Modify(o -> ch[1] , l , r , val);
            }
            o -> up();
        }

        inline LL ask(node *o , int l , int r , int val){
            if(l <= o -> l && o -> r <= r){
                return o -> col[val];
            }
            LL res = 0;
            if(l <= o -> mid()){
                res += ask(o -> ch[0] , l , r , val);
            }
            if(r > o -> mid()){
                res += ask(o -> ch[1] , l , r , val);
            }
            return res;
        }

        inline LL ask_tree(int x , int y , int val){
            LL res = 0;
            while(top[x] != top[y]){
                if(dep[top[x]] < dep[top[y]]) swap(x , y);
                res += ask(root , dfn[top[x]] , dfn[x] , val);
                x = fa[top[x]];
            }
            if(dep[x] < dep[y]) swap(x , y);
            res += ask(root , dfn[y] , dfn[x] , val);
            return res;
        }

    public:

        inline void add(int x , int y){
            head[x] = new Edge(y , head[x]);
        }

        inline void build(int n){
            dfs1(1 , 0); dfs2(1 , 1);
            build(root , 1 , n);
        }

        inline void Modify_point(int x , int val){
            Modify(root , dfn[x] , dfn[x] , val);
        }

        inline LL ask(int u , int v , int val){
            return ask_tree(u , v , val);
        }

        inline void init(){
            if(root){ delete root; root = NULL; }
            cnt = 0;
            memset(head , 0 , sizeof(head));
            memset(dep , 0 , sizeof(dep));
            memset(size , 0 , sizeof(size));
            memset(top , 0 , sizeof(top));
            // memset(id , 0 , sizeof(id));
            memset(fa , 0 , sizeof(fa));
            memset(dfn , 0 , sizeof(dfn)); 
            memset(son , 0 , sizeof(son));
        }
}yuni;

inline int Ame_(){
    // freopen("count.in" , "r" , stdin);
    // freopen("count.out" , "w" , stdout);
    mian(t);
    for(; t --> 0 ;){
        yuni.init(); mian(n) , mian(m);
        for(int i = 1;i <= n;i ++){
            mian(a[i]);
        }
        for(int i = 1;i < n;i ++){
            mian(x) , mian(y);
            yuni.add(x , y); yuni.add(y , x);
        }
        yuni.build(n);
        for(; m --> 0 ;){
            mian(opt);
            if(opt == 1) mian(x) , mian(y) , yuni.Modify_point(x , y);
            if(opt == 2) mian(x) , mian(y) , mian(z) , printf("%lld\n" , yuni.ask(x , y , z));
        }
    }
    fclose(stdin); fclose(stdout);
    return ~~(0^_^0);
}
    
int Ame__ = Ame_();
    
int main(){;}

/*
3
5 5
3 2 1 1 1
1 2
2 3
2 5
3 4
2 3 4 1
1 2 1
2 3 5 1
2 1 5 3
2 4 4 3
5 5
1 2 1 2 2
1 2
2 3
2 4
3 5
1 1 2
1 3 2
1 2 2
2 4 2 2
2 1 4 1
5 5
2 1 1 1 1
1 2
1 4
2 3
4 5
2 4 2 1
1 1 1
2 1 4 1
2 3 3 1
2 2 2 2
*/
2020/9/21 09:26
加载中...