对于此代码,多组询问的时候要新建线段树,我用的指针但是删内存的方法好像不太对(,到底应该怎么删内存?
#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
*/