【模板】数据结构
数据结构
树
- 权值 BIT 上二分
struct {
int n,t[N];
void add(int i,int x) { for(;i<=n;i+=i&-i)t[i]+=x; }
int sum(int l,int r) {
int res=0; for(--l;r>l;r-=r&-r)res+=t[r];
for(;l>r;l-=l&-l)res-=t[l]; return res;
}
int kth(int k) {
int p = 0;
rFor(i,__lg(n),0) if( p+(1<<i) < n && k > t[p+(1<<i)] ) p += 1<<i, k -= t[p];
return p+1;
}
} ;
- zkw 线段树
区间加,区间和
int tn;
LL t[N*4],add[N*4];
void bld() {
tn = 1 << __lg(n+1)+1;
For(i,1,n) t[tn+i] = a[i];
rFor(i,tn-1,1) t[i] = t[i<<1] + t[i<<1|1];
}
void mdf(int l,int r,LL x) {
int sizl = 0, sizr = 0, len = 1;
for(l = tn+l-1, r = tn+r+1; l^r^1; l/=2, r/=2, len*=2) {
t[l] += x*sizl, t[r] += x*sizr;
if( ~l & 1 ) add[l^1] += x, t[l^1] += x*len, sizl += len;
if( r & 1 ) add[r^1] += x, t[r^1] += x*len, sizr += len;
}
for(; l; l/=2, r/=2) t[l] += x*sizl, t[r] += x*sizr;
}
LL qry(int l,int r) {
int sizl = 0, sizr = 0, len = 1; LL res = 0;
for(l = tn+l-1, r = tn+r+1; l^r^1; l/=2, r/=2, len*=2) {
res += add[l]*sizl + add[r]*sizr;
if( ~l & 1 ) res += t[l^1], sizl += len;
if( r & 1 ) res += t[r^1], sizr += len;
}
for(; l; l/=2, r/=2) res += add[l]*sizl + add[r]*sizr;
return res;
}
- 权值线段树合并,分裂
#define ls(u) t[u].ch[0]
#define rs(u) t[u].ch[1]
#define mid (l+r>>1)
int ind,bin[N];
struct { int ch[2]; LL siz; } t[N*];
void delnode(int u) { t[u] = {0,0,0}, bin[++bin[0]] = u; }
int newnode() { return bin[0] ? bin[bin[0]--] : ++ind; }
void up(int u) { t[u].siz = t[ls(u)].siz + t[rs(u)].siz; }
int merge(int u,int v) {
if( !u || !v ) return u | v;
ls(u) = merge(ls(u),ls(v)), rs(u) = merge(rs(u),rs(v)), t[u].siz += t[v].siz;
return delnode(v), u;
}
void split(int ql,int qr,int &u,int &v,int l=,int r=) {
if( !u || qr < l || r < ql ) return;
if( ql <= l && r <= qr ) { v = u, u = 0; return; }
v = newnode();
split(ql,qr,ls(u),ls(v),l,mid), split(ql,qr,rs(u),rs(v),mid+1,r);
t[v].siz = t[ls(v)].siz + t[rs(v)].siz, t[u].siz -= t[v].siz;
}
- 李超线段树
区间插入,区间
#define ls (u<<1)
#define rs (u<<1|1)
#define mid (l+r>>1)
struct LC {
int t[N*4]; LL k[N],b[N],mn[N*4];
LC() { memset(mn,0x3f,sizeof mn); }
LL f(int i,int x) { return k[i] * x + b[i]; }
void mdf(int ql,int qr,int i,int u=1,int l=1,int r=n) {
if( qr < l || r < ql ) return;
if( ql <= l && r <= qr ) {
ckmin(mn[u], min(f(i,l),f(i,r)));
if( !t[u] ) { t[u] = i; return; }
if( f(i,mid) < f(t[u],mid) ) swap(i,t[u]);
if( f(i,l) < f(t[u],l) ) mdf(ql,qr,i,ls,l,mid);
else if( f(i,r) < f(t[u],r) ) mdf(ql,qr,i,rs,mid+1,r);
return;
}
mdf(ql,qr,i,ls,l,mid), mdf(ql,qr,i,rs,mid+1,r);
ckmin(mn[u], min(mn[ls],mn[rs]));
}
LL qry(int ql,int qr,int u=1,int l=1,int r=n) {
if( r < ql || qr < l ) return 1e18;
if( ql <= l && r <= qr ) return mn[u];
LL res = infl;
if( t[u] ) res = min(f(t[u],max(ql,l)), f(t[u],min(qr,r)));
return min({res, qry(ql,qr,ls,l,mid), qry(ql,qr,rs,mid+1,r)});
}
} lc;
全局插入,单点
#define ls(u) t[u].ch[0]
#define rs(u) t[u].ch[1]
#define mid (l+r>>1)
int rt[N];
struct LC {
int ind; LL k[N],b[N];
struct Node { int ch[2],id; } t[N*30];
LL f(int i,int x) { return k[i] * x + b[i]; }
void mdf(int i,int &u,int l=-1e5,int r=1e5) {
if( !u ) u = ++ind;
if( !t[u].id ) { t[u].id = i; return; }
if( f(i,mid) < f(t[u].id,mid) ) swap(i,t[u].id);
if( f(i,l) < f(t[u].id,l) ) mdf(i,ls(u),l,mid);
else if( f(i,r) < f(t[u].id,r) ) mdf(i,rs(u),mid+1,r);
}
void ins(LL x,LL y,int &u) { k[++k[0]] = x, b[k[0]] = y, mdf(k[0],u); }
LL qry(int x,int u,int l=-1e5,int r=1e5) {
if( !u ) return 1e18;
if( l == r ) return f(t[u].id,x);
return min(f(t[u].id,x), x<=mid?qry(x,ls(u),l,mid):qry(x,rs(u),mid+1,r));
}
int merge(int u,int v,int l=-1e5,int r=1e5) {
if( !u || !v ) return u | v;
if( l == r ) return f(t[u].id,l)<f(t[v].id,l) ? u : v;
ls(u) = merge(ls(u),ls(v),l,mid), rs(u) = merge(rs(u),rs(v),mid+1,r);
return mdf(t[v].id,u,l,r), u;
}
} lc;
- 可持久化
Trie
值域
struct {
int ind,rt[N],ch[N*31][2],siz[N*31];
void ins(int u,int v,int s) {
u = rt[u], v = rt[v] = ++ind;
rFor(i,29,0) {
bool c = s>>i&1;
ch[v][!c] = ch[u][!c], u = ch[u][c], v = ch[v][c] = ++ind,
siz[v] = siz[u] + 1;
}
}
int qry(int u,int v,int s) {
u = rt[u], v = rt[v];
int res = 0;
for(int i = 1<<29; i; i >>= 1) {
bool c = ~s&i;
if( siz[ch[u][c]] < siz[ch[v][c]] ) res |= i, u = ch[u][c], v = ch[v][c];
else u = ch[u][!c], v = ch[v][!c];
}
return res;
}
} ;
- 笛卡尔树
升序 BST 以
void bld() {
For(i,1,n) {
int tmp = tp;
while( tp && a[i] < a[stk[tp]] ) --tp;
if( tp ) ch[stk[tp]][1] = i;
if( tp < tmp ) ch[i][0] = stk[tp+1];
stk[++tp] = i;
}
}
- 可持久化文艺平衡树
空间限制
// LG5586 [P5350] 序列 (加强版)
#define ls(u) t[u].ch[0]
#define rs(u) t[u].ch[1]
const int N = 3e5+5, M = 5e6;
int ind,rt,n,a[N],len[N];
struct Node { int ch[2],siz,len; mint val,sum,add; bool rev; } t[M+N];
int node(int len,mint x)
{ return t[++ind] = {0,0,len,len,x,len*x,0,0}, ind; }
int node(const Node &x){ return t[++ind] = x, ind; }
void up(int u) {
t[u].siz = t[ls(u)].siz + t[rs(u)].siz + t[u].len,
t[u].sum = t[ls(u)].sum + t[rs(u)].sum + t[u].len*t[u].val;
}
void down(int u,mint x,bool y) {
if( x.x ) t[u].val += x, t[u].add += x, t[u].sum += t[u].siz * x;
if( y ) t[u].rev ^= y, swap(ls(u),rs(u));
}
void down(int u) { if( t[u].add.x || t[u].rev ) {
if( ls(u) ) down( ls(u)=node(t[ls(u)]) ,t[u].add,t[u].rev);
if( rs(u) ) down( rs(u)=node(t[rs(u)]) ,t[u].add,t[u].rev);
t[u].add = t[u].rev = 0;
}}
void dfs(int u) {
down(u);
if( ls(u) ) dfs(ls(u));
if( n && a[n] == t[u].val.x ) len[n] += t[u].len;
else a[++n] = t[u].val.x, len[n] = t[u].len;
if( rs(u) ) dfs(rs(u));
}
int bld(int l=1,int r=n) {
if( l > r ) return 0;
int mid = l+r>>1, u = node(len[mid],a[mid]);
return ls(u) = bld(l,mid-1), rs(u) = bld(mid+1,r), up(u), u;
}
void rbld() { n = 0, dfs(rt), ind = 0, rt = bld(); }
void split(int u,int k,int &l,int &r) {
if( !u ) { l = r = 0; return; }
down(u);
if( t[ls(u)].siz < k && k < t[ls(u)].siz+t[u].len ) {
int mid = k-t[ls(u)].siz, v = node(t[u]);
t[v].len = t[u].len-mid, t[u].len = mid;
ls(v) = 0, rs(u) = v, up(v), up(u);
}
if( k <= t[ls(u)].siz ) r = node(t[u]), split(ls(r),k,l,ls(r)), up(r);
else l = node(t[u]), split(rs(l),k-t[ls(l)].siz-t[l].len,rs(l),r), up(l);
}
int merge(int l,int r) {
if( !l || !r ) return l | r;
int u;
if( mt()%(t[l].siz+t[r].siz) < t[l].siz )
down(u=node(t[l])), rs(u) = merge(rs(u),r);
else down(u=node(t[r])), ls(u) = merge(l,ls(u));
return up(u), u;
}
mint sum(int l,int r) { // ask sum of [l,r]
int a,b,c; split(rt,r,b,c), split(b,l-1,a,b);
mint res = t[b].sum;
rt = merge(merge(a,b),c);
return res;
}
void cov(int l,int r,int x) { // let [l,r] = x
int a,b,c; split(rt,r,b,c), split(b,l-1,a,b);
rt = merge(merge(a,node(r-l+1,x)),c);
}
void add(int l,int r,int x) { // let [l,r] += x
int a,b,c; split(rt,r,b,c), split(b,l-1,a,b);
down(b,x,0);
rt = merge(merge(a,b),c);
}
void copy(int l1,int r1,int l2,int r2) { // let [l2,r2] = [l1,r1]
int a,b,c,d,e; bool flg = 0;
if( l1 > l2 ) swap(l1,l2), swap(r1,r2), flg = 1;
split(rt,r2,d,e), split(d,l2-1,c,d), split(c,r1,b,c), split(b,l1-1,a,b);
rt = merge(merge(merge(merge(a,!flg?b:d),c),!flg?b:d),e);
}
void swap(int l1,int r1,int l2,int r2) { // swap [l1,r1] and [l2,r2]
if( l1 > l2 ) swap(l1,l2), swap(r1,r2);
int a,b,c,d,e;
split(rt,r2,d,e), split(d,l2-1,c,d), split(c,r1,b,c), split(b,l1-1,a,b);
rt = merge(merge(merge(merge(a,d),c),b),e);
}
void rev(int l,int r) { // reverse [l,r]
int a,b,c; split(rt,r,b,c), split(b,l-1,a,b);
down(b,0,1);
rt = merge(merge(a,b),c);
}
void dbg() {
n = 0, dfs(rt);
For(i,1,n, p = 1) {
if( len[i] > 1 ) cerr<<"["<<p<<","<<p+len[i]-1<<"]:";
cerr<<a[i]<<(i<n?' ':'\n');
p += len[i];
}
}
signed main() {
cin>>n>>m; For(i,1,n) cin>>a[i], len[i] = 1;
rt = bld();
while( m-- ) {
if( ind >= M ) rbld();
// dbg();
}
n = 0, dfs(rt); For(i,1,n) For(j,1,len[i]) cout<<a[i]<<" ";
}
- 珂朵莉树
struct CT {
int l,r;
mutable int val;
CT(int l=0,int r=0,int val=0):l(l),r(r),val(val){}
bool operator < (const CT &rhs) const { return l < rhs.l; }
}; set<CT> ct;
auto split(int p) {
auto it = --ct.upper_bound({p});
if( it->l == p ) return it;
int l = it->l, r = it->r, x = it->val;
ct.erase(it), ct.emplace(l,p-1,x);
return ct.emplace(p,r,x).fi;
}
void assign(int l,int r,int x) {
auto itr = split(r+1), itl = split(l);
// if( itr != ct.end() && x == itr->val ) r = (itr++)->r;
// if( itl != ct.begin() && x == prev(itl)->val) l = (--itl)->l;
ct.erase(itl,itr), ct.emplace(l,r,x);
}
-
KDT
-
LCT
#define ls(u) t[u].ch[0]
#define rs(u) t[u].ch[1]
struct {
struct Node { int fa,ch[2]; bool rev; } t[];
void rev(int u) { swap(ls(u),rs(u)), t[u].rev ^= 1; }
void down(int u) { if( t[u].rev ) rev(ls(u)), rev(rs(u)), t[u].rev = 0; }
bool nrt(int u) { return ls(t[u].fa)==u || rs(t[u].fa)==u; }
bool wh(int u) { return rs(t[u].fa)==u; }
void rtt(int x) {
int y = t[x].fa, z = t[y].fa, k = wh(x), w = t[x].ch[!k];
if( nrt(y) ) t[z].ch[wh(y)] = x; t[x].ch[!k] = y, t[y].ch[k] = w;
t[w].fa = y, t[y].fa = x, t[x].fa = z;
}
void splay(int u) {
static int tp,stk[N];
for(int v = stk[tp=1] = u; nrt(v); stk[++tp] = v = t[v].fa);
while( tp ) down(stk[tp--]);
for(int fa; fa = t[u].fa, nrt(u); rtt(u))
if( nrt(fa) ) rtt(wh(fa)==wh(u)?fa:u);
}
void acs(int x) {
for(int u = x, v = 0; u; u = t[v=u].fa) splay(u), rs(u) = v;
splay(x);
}
void mkrt(int u) { acs(u), rev(u); }
int fdrt(int u) {
acs(u);
while( ls(u) ) down(u), u = ls(u);
return splay(u), u;
}
void split(int u,int v) { mkrt(u), acs(v); }
void link(int u,int v) { mkrt(u), t[u].fa = v; }
void cut(int u,int v) { split(u,v), t[u].fa = ls(v) = 0; }
} ;
- 压位 trie
值域
// bzoj3685 普通van Emde Boas树
#define ctz(x) (uLL)__builtin_ctzll(x)
#define clz(x) (uLL)__builtin_clzll(x)
struct Trie {
uLL *t[4];
Trie() {
t[0] = new uLL[1<<14](), t[1] = new uLL[1<<8](),
t[2] = new uLL[1<<2](), t[3] = new uLL[1<<0]();
}
void ins(int x) {
Rep(i,0,4) {
uLL &u = t[i][x>>(i+1)*6], e = 1ull<<(x>>i*6&63);
if( u & e ) return; u |= e;
}
}
void ers(int x)
{ Rep(i,0,4) if( t[i][x>>(i+1)*6] &= ~(1ull<<(x>>i*6&63)) ) return; }
int min() {
if( !t[3][0] ) return -1;
int u = 0; rFor(i,3,0) u |= ctz(t[i][u>>(i+1)*6]) << i*6;
return u;
}
int max() {
if( !t[3][0] ) return -1;
int u = 0; rFor(i,3,0) u |= 63-clz(t[i][u>>(i+1)*6]) << i*6;
return u;
}
int suf(int x) {
Rep(i,0,4) {
int e = x>>i*6&63; uLL u = t[i][x>>(i+1)*6];
if( u>>e > 1 ) {
int res = x >> (i+1)*6 << (i+1)*6;
res |= ctz(u>>e+1)+e+1 << i*6;
rFor(j,i-1,0) res |= ctz(t[j][res>>(j+1)*6]) << j*6;
return res;
}
}
return -1;
}
int pre(int x) {
Rep(i,0,4) {
int e = x>>i*6&63; uLL u = t[i][x>>(i+1)*6];
if( u & (1ull<<e)-1 ) {
int res = x >> (i+1)*6 << (i+1)*6;
res |= 63-clz(u&(1ull<<e)-1) << i*6;
rFor(j,i-1,0) res |= 63-clz(t[j][res>>(j+1)*6]) << j*6;
return res;
}
}
return -1;
}
int qry(int x) { return t[0][x>>6] & 1ull<<(x&63) ? 1 : -1; }
} ;
块
- 区间逆序对
LG5046 [Ynoi2019 模拟赛] Yuno loves sqrt technology I
- 区间众数
LG5048 [Ynoi2019 模拟赛] Yuno loves sqrt technology III
- 块状链表,值域分块
值域同序列长度
// LG4278 带插入区间K小值
const int N = 7e4+5, B = 512, BN = N/B+5;
struct DS { // 值域分块
int sum[BN],cnt[N];
void add(int x,int y) { sum[x/B] += y, cnt[x] += y; }
};
struct Blk : Vi {
DS ds;
void ins(int i,int x) { emplace(begin()+i,x), ds.add(x,1); }
}; vector<Blk> bk(1); // 块状链表
Pii find(int p) { // 块状链表定位 p 位置
Rep(i,0,sz(bk))
if( p < sz(bk[i]) ) return {i,p};
else p -= sz(bk[i]);
return {sz(bk)-1,sz(bk.back())};
}
void ins(int p,int x) { // p 位置前插入 x
int i,j; tie(i,j) = find(p);
bk[i].ins(j,x);
Rep(k,i+1,sz(bk)) bk[k].ds.add(x,1);
if( sz(bk[i]) > 2*B ) {
Vi a(bk[i].end()-B,bk[i].end());
bk[i].erase(bk[i].end()-B,bk[i].end()),
bk.emplace(bk.begin()+i+1,Blk()), bk[i+1].ds = bk[i].ds;
for(int k : a) bk[i].ds.add(k,-1), bk[i+1].pb(k);
}
}
void mdf(int p,int x) { // p 位置的值改为 x
int i,j; tie(i,j) = find(p);
int y = bk[i][j]; bk[i][j] = x;
Rep(k,i,sz(bk)) bk[k].ds.add(x,1), bk[k].ds.add(y,-1);
}
int qry(int l,int r,int x) { // 查询 [l,r] 第 x 小
static DS ds;
int li,lj,ri,rj; tie(li,lj) = find(l), tie(ri,rj) = find(r);
auto add=[&](int y) {
if( li == ri ) For(i,lj,rj) ds.add(bk[li][i],y);
else {
Rep(i,lj,sz(bk[li])) ds.add(bk[li][i],y);
For(i,0,rj) ds.add(bk[ri][i],y);
}
};
add(1);
for(int i = 0; ; ++i) {
int y = ds.sum[i] + (li<ri?bk[ri-1].ds.sum[i]-bk[li].ds.sum[i]:0);
if( x > y ) x -= y;
else {
i = i*B-1;
do
++i,
x -= ds.cnt[i] + (li<ri?bk[ri-1].ds.cnt[i]-bk[li].ds.cnt[i]:0);
while( x > 0 );
add(-1);
return i;
}
}
}
莫队
- 莫队二次离线
LG5047 [Ynoi2019 模拟赛] Yuno loves sqrt technology II
区间逆序对
const int N = 1e5+5, B = 313;
int n,m,a[N],in[N];
LL f[N],g[N],ans[N];
VI lsh;
struct Q { int id,l,r; } q[N];
struct Node {
int id,op,l,r;
Node(int a=0,int b=0,int c=0,int d=0){ id=a,op=b,l=c,r=d; }
}; vector<Node> q1[N],q2[N];
struct BIT {
int t[N];
void add(int i) { for(;i<=n;i+=i&-i)++t[i]; }
int sum(int i) { int res=0;for(;i;i-=i&-i)res+=t[i];return res; }
} bit;
struct Block {
int add[N],sum[N];
void clr() { mem(add,0,in[n]), mem(sum,0,n); }
void mdf(int p) {
for(int i = p; in[i] == in[p]; ++i) ++sum[i];
For(i,in[p]+1,in[n]) ++add[i];
}
int qry(int p) { return sum[p] + add[in[p]]; }
} blk;
void mo() {
For(i,1,n) in[i] = (i+B-1)/B;
For(i,1,m) q[i].id = i, read(q[i].l,q[i].r);
sort(q+1,q+m+1,[](const Q &x,const Q &y)
{return in[x.l]!=in[y.l]?x.l<y.l:in[x.l]&1?x.r<y.r:x.r>y.r;});
For(i,1,m, l = 1, r = 0) {
if( r < q[i].r )
ans[q[i].id] += f[q[i].r]-f[r], q1[l-1].pb(q[i].id,-1,r+1,q[i].r),
r = q[i].r;
if( q[i].l < l )
ans[q[i].id] += g[q[i].l]-g[l], q2[r+1].pb(q[i].id,-1,q[i].l,l-1),
l = q[i].l;
if( q[i].r < r )
ans[q[i].id] -= f[r]-f[q[i].r], q1[l-1].pb(q[i].id,1,q[i].r+1,r),
r = q[i].r;
if( l < q[i].l )
ans[q[i].id] -= g[l]-g[q[i].l], q2[r+1].pb(q[i].id,1,l,q[i].l-1),
l = q[i].l;
}
For(i,1,n) {
blk.mdf(a[i]);
for(auto j : q1[i]) For(k,j.l,j.r) ans[j.id] += j.op * (i-blk.qry(a[k]));
}
blk.clr();
rFor(i,n,1) {
blk.mdf(a[i]);
for(auto j : q2[i]) For(k,j.l,j.r) ans[j.id] += j.op * blk.qry(a[k]-1);
}
For(i,1,m) ans[q[i].id] += ans[q[i-1].id];
}
signed main() {
read(n,m); lsh.resize(n+1), lsh[0] = -1;
For(i,1,n) read(a[i]), lsh[i] = a[i];
sort(all(lsh)), lsh.erase(unique(all(lsh)),lsh.end());
For(i,1,n) a[i] = lower_bound(all(lsh),a[i])-lsh.begin();
For(i,1,n) bit.add(a[i]), f[i] = f[i-1] + i-bit.sum(a[i]);
mem(bit.t,0,n);
rFor(i,n,1) bit.add(a[i]), g[i] = g[i+1] + bit.sum(a[i]-1);
mo();
For(i,1,m) write(ans[i]);
return ocl();
}
- 树上带修莫队
LG4074 [WC2013] 糖果公园
const int N = 1e5+5;
int n,m,mm,tn,qn,a[N],p[N],b[N];
LL val[N],w[N];
vector<int> e[N];
struct Q { int l,r,t,lca,id; } q[N];
int size,ind,fa[N][17],dep[N],fi[N],se[N],id[2*N],in[2*N],cnt[N];
LL now,ans[N];
bool vis[N*2];
void dfs(int u,int f) {
fi[u] = ++ind, id[ind] = u;
dep[u] = dep[ fa[u][0]=f ]+1;
For(i,1,16) fa[u][i] = fa[fa[u][i-1]][i-1];
for(int v : e[u]) if( v != f ) dfs(v,u);
se[u] = ++ind, id[ind] = u;
}
int lca(int u,int v) {
if( dep[u] < dep[v] ) swap(u,v);
rFor(i,16,0) if( dep[fa[u][i]] >= dep[v] ) u = fa[u][i];
if( u == v ) return u;
rFor(i,16,0) if( fa[u][i] != fa[v][i] ) u = fa[u][i], v = fa[v][i];
return fa[u][0];
}
bool operator < (const Q &x,const Q &y) {
if( in[x.l] != in[y.l] ) return x.l<y.l;
if( in[x.r] != in[y.r] ) return x.r<y.r;
return x.t<y.t;
}
void add(int x) { now += val[a[x]] * w[++cnt[a[x]]]; }
void del(int x) { now -= val[a[x]] * w[cnt[a[x]]--]; }
void up(int x) {
if( !vis[x] ) add(x);
else del(x);
vis[x] ^= 1;
}
void modify(int x) {
if( vis[p[x]] ) del(p[x]);
swap(a[p[x]],b[x]);
if( vis[p[x]] ) add(p[x]);
}
signed main() {
read(n,m,mm);
For(i,1,m) read(val[i]);
For(i,1,n) read(w[i]);
for(int i = 1; i < n; ++i) {
int x,y; read(x,y);
e[x].pb(y), e[y].pb(x);
}
For(i,1,n) read(a[i]);
size = pow(n,2./3);
For(i,1,2*n) in[i] = (i-1)/size+1;
dfs(1,0);
For(i,1,mm) {
int op; read(op);
if( !op ) ++tn, read(p[tn],b[tn]);
else {
++qn;
q[qn].id = qn, q[qn].t = tn;
int x,y; read(x,y);
if( fi[x] > fi[y] ) swap(x,y);
int anc = lca(x,y);
if( anc == x ) q[qn].l = fi[x], q[qn].r = fi[y];
else q[qn].l = se[x], q[qn].r = fi[y], q[qn].lca = anc;
}
}
sort(q+1,q+qn+1);
for(int i = 1, l = 1, r = 0, t = 0; i <= qn; ++i) {
while( r < q[i].r ) up(id[++r]);
while( l > q[i].l ) up(id[--l]);
while( l < q[i].l ) up(id[l++]);
while( r > q[i].r ) up(id[r--]);
while( t < q[i].t ) modify(++t);
while( t > q[i].t ) modify(t--);
if( q[i].lca ) up(q[i].lca);
ans[q[i].id] = now;
if( q[i].lca ) up(q[i].lca);
}
For(i,1,qn) write(ans[i]);
return iocl();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具