QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#74578 | #5439. Meet in the Middle | heno239 | WA | 244ms | 29344kb | C++17 | 11.6kb | 2023-02-02 19:19:59 | 2023-02-02 19:20:01 |
Judging History
answer
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
#include<chrono>
using namespace std;
//#define int long long
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
//constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
template<typename T>
void chmin(T& a, T b) {
a = min(a, b);
}
template<typename T>
void chmax(T& a, T b) {
a = max(a, b);
}
template<typename T>
void cinarray(vector<T>& v) {
rep(i, v.size())cin >> v[i];
}
template<typename T>
void coutarray(vector<T>& v) {
rep(i, v.size()) {
if (i > 0)cout << " "; cout << v[i];
}
cout << "\n";
}
ll mod_pow(ll x, ll n, ll m = mod) {
if (n < 0) {
ll res = mod_pow(x, -n, m);
return mod_pow(res, m - 2, m);
}
if (abs(x) >= m)x %= m;
if (x < 0)x += m;
//if (x == 0)return 0;
ll res = 1;
while (n) {
if (n & 1)res = res * x % m;
x = x * x % m; n >>= 1;
}
return res;
}
//mod should be <2^31
struct modint {
int n;
modint() :n(0) { ; }
modint(ll m) {
if (m < 0 || mod <= m) {
m %= mod; if (m < 0)m += mod;
}
n = m;
}
operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
bool operator<(modint a, modint b) { return a.n < b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= (int)mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += (int)mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
if (n == 0)return modint(1);
modint res = (a * a) ^ (n / 2);
if (n % 2)res = res * a;
return res;
}
ll inv(ll a, ll p) {
return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
fact[0] = modint(1);
for (int i = 0; i < max_n - 1; i++) {
fact[i + 1] = fact[i] * modint(i + 1);
}
factinv[max_n - 1] = modint(1) / fact[max_n - 1];
for (int i = max_n - 2; i >= 0; i--) {
factinv[i] = factinv[i + 1] * modint(i + 1);
}
}
modint comb(int a, int b) {
if (a < 0 || b < 0 || a < b)return 0;
return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
if (a < 0 || b < 0 || a < b)return 0;
return fact[a] * factinv[a - b];
}
ll gcd(ll a, ll b) {
a = abs(a); b = abs(b);
if (a < b)swap(a, b);
while (b) {
ll r = a % b; a = b; b = r;
}
return a;
}
using ld = double;
//typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-10;
const ld pi = acosl(-1.0);
template<typename T>
void addv(vector<T>& v, int loc, T val) {
if (loc >= v.size())v.resize(loc + 1, 0);
v[loc] += val;
}
/*const int mn = 2000005;
bool isp[mn];
vector<int> ps;
void init() {
fill(isp + 2, isp + mn, true);
for (int i = 2; i < mn; i++) {
if (!isp[i])continue;
ps.push_back(i);
for (int j = 2 * i; j < mn; j += i) {
isp[j] = false;
}
}
}*/
//[,val)
template<typename T>
auto prev_itr(set<T>& st, T val) {
auto res = st.lower_bound(val);
if (res == st.begin())return st.end();
res--; return res;
}
//[val,)
template<typename T>
auto next_itr(set<T>& st, T val) {
auto res = st.lower_bound(val);
return res;
}
using mP = pair<modint, modint>;
mP operator+(mP a, mP b) {
return { a.first + b.first,a.second + b.second };
}
mP operator+=(mP& a, mP b) {
a = a + b; return a;
}
mP operator-(mP a, mP b) {
return { a.first - b.first,a.second - b.second };
}
mP operator-=(mP& a, mP b) {
a = a - b; return a;
}
LP operator+(LP a, LP b) {
return { a.first + b.first,a.second + b.second };
}
LP operator+=(LP& a, LP b) {
a = a + b; return a;
}
LP operator-(LP a, LP b) {
return { a.first - b.first,a.second - b.second };
}
LP operator-=(LP& a, LP b) {
a = a - b; return a;
}
mt19937 mt(time(0));
const string drul = "DRUL";
string senw = "SENW";
//DRUL,or SENW
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
//-----------------------------------------
//verified with https://yukicoder.me/problems/no/1197
//O(NlogN)
struct edge {
int to;
ll cost;
};
struct pdata {
int g, id;
ll dist;
};
struct Centroid_Decomposition {
private:
int n;
vector<vector<edge>> G;
public:
vector<vector<pdata>> vpd;
vector<vector<int>> fG; int root;
vector<vector<P>> oriv;
vector<vector<ll>> orid;
Centroid_Decomposition(int n_) {
n = n_;
G.resize(n);
fG.resize(n); root = -1;
vpd.resize(n);
oriv.resize(n);
orid.resize(n);
}
void add_edge(int a, int b, int c) {
G[a].push_back({ b,c });
G[b].push_back({ a,c });
}
void complete() {
vector<int> exi(n, 0);
vector<int> ori(n); rep(i, n)ori[i] = i;
int tmp = 0;
function<int(int, int, int&, int&)> szdfs = [&](int id, int fr, int& g, int& sz)->int {
int res = 1;
int ma = 0;
for (edge e : G[id]) {
if (tmp != exi[e.to])continue;
if (e.to == fr)continue;
int nex = szdfs(e.to, id, g, sz);
ma = max(ma, nex);
res += nex;
}
if (ma <= sz / 2 && sz - res <= sz / 2)g = id;
return res;
};
function<int(vector<int>)> cdfs = [&](vector<int> v)->int {
tmp++;
if (v.empty())return 0;
for (int id : v) {
exi[id]++;
}
int g;
int sz = v.size();
szdfs(v[0], -1, g, sz);
oriv[g].push_back({ g,-1 });
orid[g].push_back(0);
int ctmp = 0;
for (edge e : G[g]) {
if (!exi[e.to])continue;
if (exi[e.to] != tmp)continue;
vector<int> nex;
function<void(int, int, ll)> dfs = [&](int id, int fr, ll d) {
nex.push_back(id);
vpd[id].push_back({ g,ctmp,d });
oriv[g].push_back({ id,ctmp });
orid[g].push_back(d);
for (edge e : G[id]) {
if (e.to == fr)continue;
if (exi[e.to] != tmp)continue;
dfs(e.to, id, d + e.cost);
}
};
dfs(e.to, g, e.cost);
int ng = cdfs(nex);
fG[g].push_back(ng);
ctmp++;
}
for (int id : v) {
exi[id]--;
}
tmp--;
return g;
};
root = cdfs(ori);
}
};
struct Data {
ll val; int col; int id;
};
Data mem[100000][2];
void solve() {
int n, q; cin >> n >> q;
Centroid_Decomposition G(n), H(n);
rep(i, n - 1) {
int a, b, c; cin >> a >> b >> c; a--; b--;
//a = i, b = i + 1, c = 1;
G.add_edge(a, b, c);
}
rep(i, n - 1) {
int a, b, c; cin >> a >> b >> c; a--; b--;
//a = i, b = i+1, c = 1;
H.add_edge(a, b, c);
}
G.complete();
H.complete();
vector<int> qa(q), qb(q);
rep(i, q) {
cin >> qa[i] >> qb[i];qa[i]--; qb[i]--;
//qa[i] = qb[i] = 0;
//qa[i] = i % n; qb[i] = i % n;
}
vector<vector<int>>qs(n);
rep(i, q)qs[qb[i]].push_back(i);
auto& fG = H.fG;
auto& oriv = H.oriv;
auto& orid = H.orid;
rep(i, n)rep(j, 2)mem[i][j] = { -INF,-10 };
vector<bool> used(n);
vector<int> cur;
auto upd = [&](int g, Data p) {
if (!used[g]) {
used[g] = true; cur.push_back(g);
}
if (p.val > mem[g][0].val) {
swap(mem[g][0], p);
swap(mem[g][1], p);
}
else if (p.val > mem[g][1].val) {
swap(mem[g][1], p);
}
if (mem[g][0].col == mem[g][1].col) {
swap(mem[g][1], p);
}
};
vector<bool> dused[2];
rep(i, 2)dused[i].resize(n);
ll ma = -INF; int did[2];
auto init_d = [&]() {
if (ma == -INF)return;
ma = -INF;
rep(j, 2) {
int v = did[j];
dused[j][v] = false;
for (auto pre : G.vpd[v]) {
dused[j][pre.g] = false;
}
}
};
auto addmem = [&](int id, ll d) {
ll nma = -INF;
int to = -1;
if (mem[id][0].val + d > nma) {
nma = mem[id][0].val + d;
to = mem[id][0].id;
}
upd(id, { d,-1,id });
for (auto& pre : G.vpd[id]) {
int g = pre.g;
int c = pre.id;
ll nd = d + pre.dist;
rep(j, 2) {
if (mem[g][j].col != c) {
if (mem[g][j].val + pre.dist + d > nma) {
nma = mem[g][j].val + pre.dist;
to = mem[g][j].id;
}
}
}
upd(g, { nd,c,id });
}
if (nma > ma) {
if (ma != -INF) {
rep(j, 2) {
int v = did[j];
dused[j][v] = false;
for (auto pre : G.vpd[v]) {
dused[j][pre.g] = false;
}
}
}
ma = nma;
did[0] = id;
did[1] = to;
rep(j, 2) {
int v = did[j];
dused[j][v] = true;
for (auto pre : G.vpd[v]) {
dused[j][pre.g] = true;
}
}
}
if (ma == -INF) {
did[0] = id;
did[1] = id;
rep(j, 2) {
int v = did[j];
dused[j][v] = true;
for (auto pre : G.vpd[v]) {
dused[j][pre.g] = true;
}
}
}
};
auto memquery = [&](int id) {
ll res = -INF;
if (ma == -INF)return res;
rep(j, 2) {
if (dused[j][id]) {
chmax(res, mem[id][0].val);
}
else {
per(i, G.vpd[id].size()) {
int v = G.vpd[id][i].g;
if (dused[j][v]) {
int c = G.vpd[id][i].id;
ll d = G.vpd[id][i].dist;
rep(k, 2) {
if (mem[v][k].col != c) {
chmax(res, mem[v][k].val + d);
}
}
break;
}
}
}
}
return res;
};
vector<ll> ans(q, 0);
rep(i, n) {
vector<int> locs;
rep(j, oriv[i].size()) {
if (j == 0 || oriv[i][j].second != oriv[i][j - 1].second) {
locs.push_back(j);
}
}
locs.push_back(oriv[i].size());
init_d();
rep(_, locs.size() - 1) {
int le = locs[_];
int ri = locs[_ + 1];
if (_ == 0) {
Rep(j, le, ri) {
int id = oriv[i][j].first;
ll d = orid[i][j];
addmem(id, d);
}
}
//cout << "!? " << _ << " " << oriv[i][le].second << "\n";
Rep(j, le, ri) {
int id = oriv[i][j].first;
ll d = orid[i][j];
for (auto qid : qs[id]) {
ll val = memquery(qa[qid]);
val += d;
chmax(ans[qid], val);
}
}
if (_ > 0) {
Rep(j, le, ri) {
int id = oriv[i][j].first;
ll d = orid[i][j];
addmem(id, d);
}
}
}
for (int id : cur) {
rep(j, 2)mem[id][j] = { -INF,-10 };
}
init_d();
per(_, (int)locs.size() - 1) {
int le = locs[_];
int ri = locs[_ + 1];
Rep(j, le, ri) {
int id = oriv[i][j].first;
ll d = orid[i][j];
for (auto qid : qs[id]) {
ll val = memquery(qa[qid]);
val += d;
chmax(ans[qid], val);
}
}
Rep(j, le, ri) {
int id = oriv[i][j].first;
ll d = orid[i][j];
addmem(id, d);
}
}
for (int id : cur) {
rep(j, 2)mem[id][j] = { -INF,-10 };
used[id] = false;
}
cur.clear();
}
//cout << "fin\n";
rep(i, q)cout << ans[i] << "\n";
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
//cout << fixed << setprecision(10);
//init_f();
//init();
//expr();
//while(true)
//int t; cin >> t; rep(i, t)
solve();
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 1ms
memory: 11804kb
input:
3 4 1 2 1 2 3 2 1 2 2 2 3 1 1 1 1 2 2 1 2 2
output:
6 4 5 3
result:
ok 4 number(s): "6 4 5 3"
Test #2:
score: 0
Accepted
time: 6ms
memory: 12092kb
input:
2 1 1 2 1 1 2 1 1 1
output:
2
result:
ok 1 number(s): "2"
Test #3:
score: 0
Accepted
time: 7ms
memory: 13128kb
input:
2 1 1 2 1 1 2 1 1 2
output:
1
result:
ok 1 number(s): "1"
Test #4:
score: 0
Accepted
time: 213ms
memory: 29344kb
input:
10000 50000 8101 5996 108427744 5996 7605 870838849 5996 5599 603303696 8101 3006 339377417 8101 6463 442516687 6463 5560 109174079 5560 4063 127596224 3006 1682 947915262 5996 1986 130416311 6463 5455 279771516 6463 2634 516688796 4063 3034 217886863 7605 5092 742375061 5599 2266 193804402 5092 140...
output:
647838384844 626539793176 514273941704 637066393138 472546379596 645842915960 641537859258 573604504956 644081575470 803875451466 674370549986 734764046916 744862815441 763778393516 553499885160 526743824759 610373719514 689550247042 549161302822 726811438160 653134244120 666761991962 701575393972 6...
result:
ok 50000 numbers
Test #5:
score: 0
Accepted
time: 199ms
memory: 26260kb
input:
10000 50000 5314 8843 137901358 5314 4153 459134340 5314 8667 933926892 4153 6504 330487798 4153 8880 750362377 4153 5990 874275912 4153 546 563436331 5990 6216 902348875 8843 3101 669215553 6216 8138 732343176 8667 8675 581114294 6504 7416 127778711 546 4239 282695908 6504 9455 549237168 5314 8340 ...
output:
464564968641 331633000004 565299667784 484694871646 570451097836 417492802442 372302349684 638725688107 386235986078 355738655551 462027769535 558485994764 524714144289 450157947013 432701214095 494566741391 529031758638 637683369382 415646847933 344894296260 390294136162 527685175763 575151290175 3...
result:
ok 50000 numbers
Test #6:
score: 0
Accepted
time: 244ms
memory: 29152kb
input:
10000 50000 2808 2490 757309564 2808 9601 312271047 2808 4046 119325897 2808 4894 466822371 4894 1507 498399554 2490 5982 84088145 9601 1251 149019541 2808 6681 416590999 2808 6583 357757899 1251 3192 889947539 6583 9762 350572496 6681 22 597479070 5982 8744 263208242 8744 5281 49894126 1507 8806 30...
output:
1501072697023 2058806276380 2017086500812 2044250452467 1543567245539 1695101693278 1765462307870 2576423082091 2302805133490 2090282734929 2375783476943 1954788661090 2056530503168 2453153202726 1978028047409 2106220371212 2210163378358 2015714406862 1555876274751 2122832986951 2102262624814 169085...
result:
ok 50000 numbers
Test #7:
score: -100
Wrong Answer
time: 236ms
memory: 28632kb
input:
10000 50000 4064 7188 81750473 7188 8466 310631946 8466 2276 154981798 2276 7347 162965456 7188 464 806245243 464 2250 849189978 8466 641 734602751 8466 9246 225800419 4064 5267 191524437 2276 5292 192776095 2276 9036 414997994 9246 5470 362146726 2250 473 98496385 4064 7726 700294189 473 9503 42824...
output:
3589143478793 5241855728342 3397106617685 3432843859461 4331155576344 3649934075137 3020107625030 3297847713344 3894730366667 3030559097282 4824131552194 4821302024170 4471510161493 3291683748595 4954639576578 2961243269520 3659899432127 3421183608349 4971502364580 4408705330639 5057851173289 500158...
result:
wrong answer 5th numbers differ - expected: '4544481241003', found: '4331155576344'