結果
| 問題 |
No.2163 LCA Sum Query
|
| コンテスト | |
| ユーザー |
snuke
|
| 提出日時 | 2022-12-16 21:53:37 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 687 ms / 6,000 ms |
| コード長 | 8,778 bytes |
| コンパイル時間 | 2,447 ms |
| コンパイル使用メモリ | 214,820 KB |
| 最終ジャッジ日時 | 2025-02-09 14:22:15 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 40 |
コンパイルメッセージ
main.cpp: In function ‘int geti()’:
main.cpp:25:23: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
25 | int geti(){int x;scanf("%d",&x);return x;}
| ~~~~~^~~~~~~~~
main.cpp: In member function ‘void Solver::solve()’:
main.cpp:303:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
303 | scanf("%d%d",&n,&q);
| ~~~~~^~~~~~~~~~~~~~
main.cpp:308:12: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
308 | scanf("%d%d",&a,&b);
| ~~~~~^~~~~~~~~~~~~~
main.cpp:317:12: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
317 | scanf("%d%d%d",&u,&r,&v);
| ~~~~~^~~~~~~~~~~~~~~~~~~
ソースコード
#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define rep1(i,n) for(int i = 1; i <= (n); ++i)
#define drep(i,n) for(int i = (n)-1; i >= 0; --i)
#define srep(i,s,t) for (int i = s; i < (t); ++i)
#define rng(a) a.begin(),a.end()
#define rrng(a) a.rbegin(),a.rend()
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define pob pop_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcountll
#define snuke srand((unsigned)clock()+(unsigned)time(NULL));
#define newline puts("")
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using PQ = priority_queue<T,vc<T>,greater<T>>;
using uint = unsigned; using ull = unsigned long long;
using vi = vc<int>; using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long; using vl = vc<ll>; using vvl = vv<ll>; using vvvl = vv<vl>;
using P = pair<int,int>; using vp = vc<P>; using vvp = vv<P>;
int geti(){int x;scanf("%d",&x);return x;}
vi pm(int n, int s=0) { vi a(n); iota(rng(a),s); return a;}
template<typename T>istream& operator>>(istream&i,vc<T>&v){rep(j,sz(v))i>>v[j];return i;}
template<typename T>string join(const T&v,const string& d=""){stringstream s;rep(i,sz(v))(i?s<<d:s)<<v[i];return s.str();}
template<typename T>ostream& operator<<(ostream&o,const vc<T>&v){if(sz(v))o<<join(v," ");return o;}
template<typename T1,typename T2>istream& operator>>(istream&i,pair<T1,T2>&v){return i>>v.fi>>v.se;}
template<typename T1,typename T2>ostream& operator<<(ostream&o,const pair<T1,T2>&v){return o<<v.fi<<","<<v.se;}
template<typename T1,typename T2>void operator--(pair<T1,T2>&a,int){a.fi--;a.se--;}
template<typename T>void operator--(vc<T>&a,int){for(T&x:a)x--;}
template<typename T>void operator++(vc<T>&a,int){for(T&x:a)x++;}
template<typename T>void operator+=(vc<T>&a,T b){for(T&x:a)x+=b;}
template<typename T>void operator+=(vc<T>&a,const vc<T>&b){a.insert(a.end(),rng(b));}
template<typename T1,typename T2>bool mins(T1& x,const T2&y){if(x>y){x=y;return true;}else return false;}
template<typename T1,typename T2>bool maxs(T1& x,const T2&y){if(x<y){x=y;return true;}else return false;}
template<typename Tx, typename Ty>Tx dup(Tx x, Ty y){return (x+y-1)/y;}
template<typename T>ll suma(const vc<T>&a){ll res(0);for(auto&&x:a)res+=x;return res;}
template<typename T>ll suma(const vv<T>&a){ll res(0);for(auto&&x:a)res+=suma(x);return res;}
template<typename T>void uni(T& a){sort(rng(a));a.erase(unique(rng(a)),a.end());}
template<typename T>void prepend(vc<T>&a,const T&x){a.insert(a.begin(),x);}
const double eps = 1e-10;
const ll LINF = 1001002003004005006ll;
const int INF = 1001001001;
#define dame { puts("-1"); return;}
#define yes { puts("Yes"); return;}
#define no { puts("No"); return;}
#define ret(x) { cout<<(x)<<endl; return;}
#define yn {puts("Yes");}else{puts("No");}
const int MX = 200005;
// Binary Indexed Tree
template<typename T=int>
struct bit {
int n; vector<T> d;
bit() {}
bit(int mx): n(mx+1), d(mx+1) {}
void add(int i, T x=1) {
for (++i;i<n;i+=i&-i) d[i] += x;
}
T sum(int i) {
T x = 0;
for (++i;i;i-=i&-i) x += d[i];
return x;
}
T sum(int l, int r) { return sum(r-1)-sum(l-1);}
};
//
// Segment tree with lazy prop
struct F {
ll s, cs;
F(ll s=0, ll cs=0):s(s),cs(cs) {}
F& operator+=(const F& f) {
s += f.s;
cs += f.cs;
return *this;
}
F operator+(const F& f) const { return F(*this) += f;}
};
ostream& operator<<(ostream&o,const F&f){return o<<f.s<<','<<f.cs;}
struct G {
int x;
G(int x=0):x(x) {}
void operator()(F& f) const {
f.s += f.cs*x;
}
void operator*=(const G& g) {
x += g.x;
}
};
ostream& operator<<(ostream&o,const G&g){return o<<g.x;}
struct F2 {
ll s2, s1, w;
F2(ll s2=0, ll s1=0, ll w=0):s2(s2),s1(s1),w(w) {}
F2& operator+=(const F2& f) {
s2 += f.s2;
s1 += f.s1;
w += f.w;
return *this;
}
F2 operator+(const F2& f) const { return F2(*this) += f;}
};
ostream& operator<<(ostream&o,const F2&f){return o<<f.s2<<','<<f.s1;}
struct G2 {
int x;
G2(int x=0):x(x) {}
void operator()(F2& f) const {
f.s2 += (f.s1*2 + f.w*x)*x;
f.s1 += f.w*x;
}
void operator*=(const G2& g) {
x += g.x;
}
};
ostream& operator<<(ostream&o,const G2&g){return o<<g.x;}
template<typename F, typename G>
struct seg {
struct FG {
F f; G g;
void apply(const G& _g) {
_g(f);
g *= _g;
}
};
vector<FG> d; int n;
seg(){}
seg(int mx) {
n = 1; while (n < mx) n <<= 1;
d = vector<FG>(n<<1);
}
int width(int i) { return 1<<(__builtin_clz(i)-__builtin_clz(n));}
void upd(int i) { d[i].f = d[i<<1].f+d[i<<1|1].f;}
FG& operator[](int i) { return d[n+i];}
void init() { drep(i,n) upd(i);}
void prop(int i) {
d[i<<1].apply(d[i].g);
d[i<<1|1].apply(d[i].g);
d[i].g = G();
}
void add(int l, int r, G g) { if (l < r) add(l,r,g,1,0,n);}
void add(int a, int b, const G& g, int i, int l, int r) {
if (a <= l && r <= b) {
d[i].apply(g);
return;
}
prop(i);
int c = (l+r)>>1;
if (a < c) add(a,b,g,i<<1,l,c);
if (c < b) add(a,b,g,i<<1|1,c,r);
upd(i);
}
void add(int v, F f) {
int i = 1;
for (int b = n; i < n; b >>= 1, i = i<<1|!!(v&b)) prop(i);
d[i].f += f;
while (i > 1) i >>= 1, upd(i);
}
F get(int l, int r) { return (l < r) ? get(l,r,1,0,n) : F();}
F get(int a, int b, int i, int l, int r) {
if (a <= l && r <= b) return d[i].f;
prop(i);
int c = (l+r)>>1;
F res;
if (a < c) res += get(a,b,i<<1,l,c);
if (c < b) res += get(a,b,i<<1|1,c,r);
return res;
}
void print() {
srep(i,1,n*2) cerr<<d[i].f<<' ';
cerr << endl;
srep(i,1,n*2) cerr<<d[i].g<<' ';
cerr << endl;
}
};
//
// HL-decomposition
struct hl {
int n, root, tot;
vvi to;
seg<F,G> t;
seg<F2,G2> t2;
bit<int> nt;
hl(int n=0):n(n),to(n) {}
void addEdge(int a, int b) {
to[a].pb(b);
to[b].pb(a);
}
vi tsz, pa, dep;
int tfs(int v, int p=-1) {
pa[v] = p;
tsz[v] = 1;
rep(i,sz(to[v])) {
int& u = to[v][i];
if (u == p) swap(u, to[v].back());
if (u == p) break;
dep[u] = dep[v]+1;
tsz[v] += tfs(u,v);
if (tsz[u] > tsz[to[v][0]]) swap(u, to[v][0]);
}
if (~p) to[v].pop_back();
return tsz[v];
}
vi in, out, nxt, kv;
void dfs(int v) {
in[v] = sz(kv); kv.pb(v);
rep(i,sz(to[v])) {
int u = to[v][i];
nxt[u] = i ? u : nxt[v];
dfs(u);
}
out[v] = sz(kv);
}
void init(int v=0) {
tsz = pa = dep = vi(n);
tfs(root = v);
in = out = nxt = vi(n);
nxt[root] = root;
dfs(root);
t = seg<F,G>(n);
t2 = seg<F2,G2>(n);
rep(i,n) if (i != v) t2[in[i]].f.w = i-pa[i];
t2.init();
nt = bit(n);
tot = 0;
}
int up(int v, int l) {
while (~v) {
int u = nxt[v], nl = dep[v]-dep[u]+1;
if (l < nl) return kv[in[v]-l];
l -= nl; v = pa[u];
}
return -1;
}
int lca(int a, int b) {
while (nxt[a] != nxt[b]) {
if (in[a] < in[b]) swap(a,b);
a = pa[nxt[a]];
}
if (in[a] < in[b]) swap(a,b);
return b;
}
int len(int a, int b) { return dep[a]+dep[b]-dep[lca(a,b)]*2;}
//* // SEG
int num(int v) {
return nt.sum(in[v], out[v]);
}
void add(int v, int co=1) {
int _v = v;
if (co == -1) nt.add(in[_v],-1);
int pc = 0;
while (~v) {
int u = nxt[v];
t.add(in[v], F(ll(num(v)-pc)*(v+1)*co, (v+1)*co));
t.add(in[u], in[v], G(co));
t2.add(in[u], in[v]+1, G2(co));
v = pa[u];
pc = num(u);
}
if (co == 1) nt.add(in[_v],1);
tot += co;
}
ll getr(int v) { return t.get(in[v], out[v]).s;}
ll getv(int v) {
ll res = getr(0);
if (v) {
F2 f;
while (~v) {
int u = nxt[v];
f += t2.get(in[u], in[v]+1);
v = pa[u];
}
res += f.s1*tot - f.s2;
}
return res;
}
ll get(int r, int v) {
if (lca(r,v) != v) return getr(v);
ll res = getv(v);
if (v == r) return res;
r = up(r, dep[r]-dep[v]-1);
res -= getr(r);
int c = num(r);
res -= ll(v+1)*c*(tot-c);
return res;
}
//*/
};
//
struct Solver {
void solve() {
int n,q;
scanf("%d%d",&n,&q);
hl t(n);
rep(i,n-1) {
int a,b;
scanf("%d%d",&a,&b);
--a; --b;
t.addEdge(a,b);
}
t.init();
vi c(n);
rep(qi,q) {
int u,r,v;
scanf("%d%d%d",&u,&r,&v);
--u; --r; --v;
t.add(u, c[u]?-1:1);
c[u] ^= 1;
ll ans = t.get(r,v);
printf("%lld\n",ans);
}
}
};
int main() {
// cin.tie(nullptr); ios::sync_with_stdio(false);
int ts = 1;
// scanf("%d",&ts);
rep1(ti,ts) {
Solver solver;
solver.solve();
}
return 0;
}
snuke