2023 rcpc
This commit is contained in:
308
2023/rcpc/d2/editorial/f-suceava-663.cpp
Normal file
308
2023/rcpc/d2/editorial/f-suceava-663.cpp
Normal file
@@ -0,0 +1,308 @@
|
||||
#include <bits/stdc++.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
ofstream out("f.out");
|
||||
|
||||
const int MOMMAX = 5e5;
|
||||
|
||||
struct edge
|
||||
{
|
||||
int ti,tf,x,y;
|
||||
};
|
||||
|
||||
int n,m,t,q;
|
||||
vector<int>g[100005];
|
||||
map<pair<int,int>,int>color;
|
||||
map<pair<int,int>,int>beg;
|
||||
vector<edge>v[100005];
|
||||
vector<pair<int,int>>qs[100005];///timp,index
|
||||
vector<pair<int,int>>aint[4 * MOMMAX + 5];
|
||||
vector<pair<int,int>>input_edges;
|
||||
vector<int>inds[4 * MOMMAX + 5];
|
||||
int ans[100005];
|
||||
int diammax[4 * MOMMAX + 5];
|
||||
int tata[100005],sz[100005],diam[100005];
|
||||
pair<int,int>bestdiam[100005];
|
||||
|
||||
vector<int> rmq[19];
|
||||
int tin[100005], depth[100005];
|
||||
|
||||
void _dfs(int u = 1, int v = 0) {
|
||||
tin[u] = rmq[0].size();
|
||||
rmq[0].emplace_back(u);
|
||||
for(const auto &it: g[u]) if(it != v) {
|
||||
depth[it] = depth[u] + 1;
|
||||
_dfs(it, u);
|
||||
rmq[0].emplace_back(u);
|
||||
}
|
||||
}
|
||||
|
||||
int _min(int u, int v) {
|
||||
if(depth[u] < depth[v]) {
|
||||
return u;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
void init() {
|
||||
_dfs();
|
||||
int n = rmq[0].size();
|
||||
for(int i = 1; (1 << i) <= n; i++) {
|
||||
for(int j = 0; j + (1 << i) - 1 < n; j++) {
|
||||
rmq[i].emplace_back(_min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int query(int l, int r) {
|
||||
int lg = __lg(r - l + 1);
|
||||
return _min(rmq[lg][l], rmq[lg][r - (1 << lg) + 1]);
|
||||
}
|
||||
|
||||
int lca(int u, int v) {
|
||||
int l = tin[u], r = tin[v];
|
||||
if(l > r) {
|
||||
swap(l, r);
|
||||
}
|
||||
return query(l, r);
|
||||
}
|
||||
|
||||
int dist(int u, int v) {
|
||||
return depth[u] + depth[v] - 2 * depth[lca(u, v)];
|
||||
}
|
||||
|
||||
void update(int nod,int l,int r,int st,int dr,pair<int,int>p)
|
||||
{
|
||||
if (r < st or dr < l)
|
||||
return;
|
||||
if (st <= l and r <= dr)
|
||||
{
|
||||
aint[nod].push_back(p);
|
||||
return;
|
||||
}
|
||||
int mij = (l + r) / 2;
|
||||
update(2 * nod,l,mij,st,dr,p);
|
||||
update(2 * nod + 1,mij + 1,r,st,dr,p);
|
||||
}
|
||||
|
||||
void setquery(int nod,int l,int r,int pos,int index)
|
||||
{
|
||||
if (l == r)
|
||||
inds[nod].push_back(index);
|
||||
else
|
||||
{
|
||||
int mij = (l + r) / 2;
|
||||
if (pos <= mij)
|
||||
setquery(2 * nod,l,mij,pos,index);
|
||||
else
|
||||
setquery(2 * nod + 1,mij + 1,r,pos,index);
|
||||
}
|
||||
}
|
||||
|
||||
struct stack_upd
|
||||
{
|
||||
int x,y,antx;
|
||||
pair<int,int>antbestx;
|
||||
///x a devenit tatal lui y
|
||||
///x avea diam antx
|
||||
///size-ul anterior al lui y o sa ramana in sz[y]
|
||||
///diametrul anterior al lui y o sa ramane in diam[y]
|
||||
};
|
||||
|
||||
stack<stack_upd>stk;
|
||||
|
||||
int reprez(int x)
|
||||
{
|
||||
while (x != tata[x])
|
||||
x = tata[x];
|
||||
return x;
|
||||
}
|
||||
|
||||
void baga(int nod,int x,int y)
|
||||
{
|
||||
//cout << "super" << endl;
|
||||
x = reprez(x);
|
||||
y = reprez(y);
|
||||
if (sz[x] < sz[y])
|
||||
swap(x,y);
|
||||
stack_upd aux;
|
||||
aux.x = x;
|
||||
aux.y = y;
|
||||
aux.antbestx = bestdiam[x];
|
||||
aux.antx = diam[x];
|
||||
stk.push(aux);
|
||||
tata[aux.y] = aux.x;
|
||||
int maxim = max(diam[x],diam[y]);
|
||||
maxim = max(maxim,dist(bestdiam[x].first,bestdiam[y].first));
|
||||
maxim = max(maxim,dist(bestdiam[x].first,bestdiam[y].second));
|
||||
maxim = max(maxim,dist(bestdiam[x].second,bestdiam[y].first));
|
||||
maxim = max(maxim,dist(bestdiam[x].second,bestdiam[y].second));
|
||||
//cout << x << ' ' << y << ' ' << diam[x] << ' ' << diam[y] << ' ' << dist(bestdiam[x].first,bestdiam[y].first) << ' ' << dist(bestdiam[x].first,bestdiam[y].second) << ' ' << dist(bestdiam[x].second,bestdiam[y].first) << ' ' << dist(bestdiam[x].second,bestdiam[y].second) << endl;
|
||||
diammax[nod] = max(diammax[nod],maxim);
|
||||
if (diam[x] == maxim)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (diam[y] == maxim)
|
||||
{
|
||||
diam[x] = diam[y];
|
||||
bestdiam[x] = bestdiam[y];
|
||||
return;
|
||||
}
|
||||
if (dist(bestdiam[x].first,bestdiam[y].first) == maxim)
|
||||
{
|
||||
diam[x] = dist(bestdiam[x].first,bestdiam[y].first);
|
||||
bestdiam[x] = {bestdiam[x].first,bestdiam[y].first};
|
||||
return;
|
||||
}
|
||||
if (dist(bestdiam[x].first,bestdiam[y].second) == maxim)
|
||||
{
|
||||
diam[x] = dist(bestdiam[x].first,bestdiam[y].second);
|
||||
bestdiam[x] = {bestdiam[x].first,bestdiam[y].second};
|
||||
return;
|
||||
}
|
||||
if (dist(bestdiam[x].second,bestdiam[y].first) == maxim)
|
||||
{
|
||||
diam[x] = dist(bestdiam[x].second,bestdiam[y].first);
|
||||
bestdiam[x] = {bestdiam[x].second,bestdiam[y].first};
|
||||
return;
|
||||
}
|
||||
if (dist(bestdiam[x].second,bestdiam[y].second) == maxim)
|
||||
{
|
||||
diam[x] = dist(bestdiam[x].second,bestdiam[y].second);
|
||||
bestdiam[x] = {bestdiam[x].second,bestdiam[y].second};
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void rollback()
|
||||
{
|
||||
stack_upd aux = stk.top();
|
||||
stk.pop();
|
||||
tata[aux.y] = aux.y;
|
||||
sz[aux.x] -= sz[aux.y];
|
||||
diam[aux.x] = aux.antx;
|
||||
bestdiam[aux.x] = aux.antbestx;
|
||||
}
|
||||
|
||||
void dfs(int nod,int l,int r)
|
||||
{
|
||||
/*if (!aint[nod].empty())
|
||||
{
|
||||
cout << nod << ' ' << l << ' ' << r << endl;
|
||||
for (auto it : aint[nod])
|
||||
cout << it.first << ' ' << it.second << endl;
|
||||
cout << endl;
|
||||
}*/
|
||||
diammax[nod] = diammax[nod / 2];
|
||||
for (auto it : aint[nod])
|
||||
baga(nod,it.first,it.second);
|
||||
//if (!aint[nod].empty() or !inds[nod].empty())
|
||||
// cout << nod << ' ' << l << ' ' << r << ' ' << diammax[nod] << '\n';
|
||||
if (l == r)
|
||||
{
|
||||
for (auto it : inds[nod])
|
||||
ans[it] = diammax[nod];
|
||||
}
|
||||
else
|
||||
{
|
||||
int mij = (l + r) / 2;
|
||||
dfs(2 * nod,l,mij);
|
||||
dfs(2 * nod + 1,mij + 1,r);
|
||||
}
|
||||
for (int i = 0; i < aint[nod].size(); i++)
|
||||
rollback();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
ios_base::sync_with_stdio(false);
|
||||
cin.tie(NULL);
|
||||
cout.tie(NULL);
|
||||
cin >> n >> m;
|
||||
for (int i = 1; i < n; i++)
|
||||
{
|
||||
int x,y,cc;
|
||||
cin >> x >> y >> cc;
|
||||
if (x > y)
|
||||
swap(x,y);
|
||||
color[{x,y}] = cc;
|
||||
g[x].push_back(y);
|
||||
g[y].push_back(x);
|
||||
beg[{x,y}] = 1;
|
||||
input_edges.push_back({x,y});
|
||||
}
|
||||
for (int i = 1; i <= n; i++)
|
||||
tata[i] = i,sz[i] = 1,diam[i] = 0,bestdiam[i] = {i,i};
|
||||
init();
|
||||
cin >> t;
|
||||
for (int i = 1; i <= t; i++)
|
||||
{
|
||||
int x,y,cc;
|
||||
cin >> x >> y >> cc;
|
||||
if (x > y)
|
||||
swap(x,y);
|
||||
edge aux;
|
||||
aux.x = x;
|
||||
aux.y = y;
|
||||
aux.ti = beg[{x,y}];
|
||||
aux.tf = i;
|
||||
v[color[{x,y}]].push_back(aux);
|
||||
color[{x,y}] = cc;
|
||||
beg[{x,y}] = i + 1;
|
||||
}
|
||||
for (int i = 0; i < n - 1; i++)
|
||||
{
|
||||
int x = input_edges[i].first,y = input_edges[i].second;
|
||||
edge aux;
|
||||
aux.x = x;
|
||||
aux.y = y;
|
||||
aux.tf = t + 1;
|
||||
aux.ti = beg[{x,y}];
|
||||
v[color[{x,y}]].push_back(aux);
|
||||
}
|
||||
cin >> q;
|
||||
for (int i = 1; i <= q; i++)
|
||||
{
|
||||
int cc,tmp;
|
||||
cin >> cc >> tmp;
|
||||
tmp++;
|
||||
qs[cc].push_back({tmp,i});
|
||||
}
|
||||
int ft = 0;
|
||||
for (int i = 1; i <= m; i++)
|
||||
{
|
||||
//cout << i << endl;
|
||||
vector<int>vals;
|
||||
for (auto it : v[i])
|
||||
vals.push_back(it.ti),vals.push_back(it.tf);
|
||||
for (auto it : qs[i])
|
||||
vals.push_back(it.first);
|
||||
sort(vals.begin(),vals.end());
|
||||
if (vals.size() == 0)
|
||||
continue;
|
||||
map<int,int>mpnorma;
|
||||
int posnorma = 0;
|
||||
for (auto it : vals)
|
||||
if (!mpnorma[it])
|
||||
mpnorma[it] = ++posnorma;
|
||||
for (int j = 0; j < v[i].size(); j++)
|
||||
v[i][j].ti = mpnorma[v[i][j].ti] + ft,v[i][j].tf = mpnorma[v[i][j].tf] + ft;
|
||||
for (int j = 0; j < qs[i].size(); j++)
|
||||
qs[i][j].first = mpnorma[qs[i][j].first] + ft;
|
||||
//for (auto it : v[i])
|
||||
// cout << it.ti << ' ' << it.tf << ' ' << it.x << ' ' << it.y << endl;
|
||||
//for (auto it : qs[i])
|
||||
// cout << it.first << ' ' << it.second << endl;
|
||||
for (int j = 0; j < v[i].size(); j++)
|
||||
update(1,1,MOMMAX,v[i][j].ti,v[i][j].tf,{v[i][j].x,v[i][j].y});
|
||||
for (int j = 0; j < qs[i].size(); j++)
|
||||
setquery(1,1,MOMMAX,qs[i][j].first,qs[i][j].second);
|
||||
ft += posnorma;
|
||||
}
|
||||
dfs(1,1,MOMMAX);
|
||||
for (int i = 1; i <= q; i++)
|
||||
cout << ans[i] << '\n';
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user