QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#291034 | #4845. DFS | Radewoosh# | ML | 8ms | 57000kb | C++23 | 7.2kb | 2023-12-26 04:32:03 | 2023-12-26 04:32:04 |
Judging History
answer
//~ while (clock()<=69*CLOCKS_PER_SEC)
//~ #pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
//~ #pragma GCC target ("avx2")
//~ #pragma GCC optimize("Ofast")
//~ #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//~ #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set =
tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
*this << "[";
for (auto it = d.b; it != d.e; ++it)
*this << ", " + 2 * (it == d.b) << *it;
ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define shandom_ruffle random_shuffle
using ll=long long;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
using vi=vector<int>;
using vll=vector<ll>;
const int nax=1000*1007;
const ll mod=998244353;
ll inv(ll v)
{
if (v<=1)
return v;
return inv(mod%v)*(mod-mod/v)%mod;
}
struct node {
int roz=1;
ll wag;
ll praw;
ll mnopra=1;
ll sumpra;
ll sumwag;
node *lew, *oj, *pra;
node() { lew=pra=oj=NULL; }
};
void update(node *v) {
if (v==NULL) return;
v->roz=1;
v->sumpra=0;
v->sumwag=0;
for (int h=0; h<2; h++) {
if (v->lew!=NULL) {
v->roz+=v->lew->roz;
(v->lew->mnopra)=(v->lew->mnopra)*(v->mnopra)%mod;
(v->sumpra)=((v->sumpra)+(v->lew->sumpra)*(v->lew->mnopra))%mod;
(v->sumwag)=((v->sumwag)+(v->lew->sumwag)*(v->lew->mnopra))%mod;
}
swap(v->lew, v->pra);
}
(v->praw)=(v->praw)*(v->mnopra)%mod;
v->mnopra=1;
(v->sumpra)=((v->sumpra)+(v->praw))%mod;
(v->sumwag)=((v->sumwag)+(v->praw)*(v->wag))%mod;
}
node *merge(node *v, node *u) {
if (v==NULL) return u;
if (u==NULL) return v;
if (rand()%(v->roz+u->roz)<(v->roz)) {
update(v);//czasem można usunąć
v->pra=merge(v->pra, u);
v->pra->oj=v;
update(v);
return v;
} else {
update(u);//czasem można usunąć
u->lew=merge(v, u->lew);
u->lew->oj=u;
update(u);
return u;
}
}
pair <node*, node*> split(node *v, const function <bool(node*)> &is_left) {
if (v==NULL)
return make_pair(v, v);
pair <node*, node*> ret;
update(v);//czasem można usunąć
v->oj=NULL;
if (is_left(v)) {
ret=split(v->pra, is_left);
v->pra=ret.first;
if (v->pra!=NULL)
v->pra->oj=v;
ret.first=v;
} else {
ret=split(v->lew, is_left);
v->lew=ret.second;
if (v->lew!=NULL)
v->lew->oj=v;
ret.second=v;
}
update(v);
return ret;
}
ll gl_help;
function <bool(node*)> cut_v(int v) {
gl_help=v;
return [](node *u)->bool {
int pom=1;
if (u->lew!=NULL) pom+=u->lew->roz;
if (pom>gl_help) return false;
gl_help-=pom;
return true;
};
}
function <bool(node*)> cut_leq(ll v) {
gl_help=v;
return [](node *u)->bool {
return (u->wag)<=gl_help;
};
}
int position(node *v) {
int ret=1;
if (v->lew!=NULL) ret+=v->lew->roz;
if (v->oj==NULL) return ret;
return position(v->oj)+ret-(v->oj->lew==v)*(v->roz+1);
}
ll daj_sumpra(node *v)
{
update(v);
if (!v)
return 0;
return v->sumpra;
}
ll daj_sumwag(node *v)
{
update(v);
if (!v)
return 0;
return v->sumwag;
}
ll minimum(node *v)
{
if (v->lew)
return minimum(v->lew);
return v->wag;
}
void przemnoz(node *v, ll w)
{
if (!v)
return;
(v->mnopra)=(v->mnopra)*w%mod;
}
int n, korz;
ll tab[nax];
vi graf[nax];
ll minipod[nax];
node *dp[nax];
vector<pair<node*,int>> ciete[nax];
vll granice;
ll wyn;
void wypisz(node *v)
{
if (!v)
return;
update(v);
wypisz(v->lew);
debug() << (v->wag) << " " << (v->praw);
wypisz(v->pra);
}
void usun(node *v)
{
if (!v)
return;
usun(v->lew);
usun(v->pra);
delete v;
}
bool mniej(int a, int b)
{
return minipod[a]<minipod[b];
}
ll sumsuf[nax];
node *merge_smart(node *a, node *b)
{
node *ret=NULL;
while(a && b)
{
ll ma=minimum(a);
ll mb=minimum(b);
if (ma>mb)
{
swap(a, b);
swap(ma, mb);
}
auto wez=split(a, cut_leq(mb));
ret=merge(ret, wez.first);
a=wez.second;
}
if (a)
ret=merge(ret, a);
if (b)
ret=merge(ret, b);
return ret;
}
void potnij(node *v, vector<pair<node*,int>> &wek)
{
while(v)
{
ll x=minimum(v);
int g=lower_bound(granice.begin(), granice.end(), x)-granice.begin();
if (g==(int)granice.size())
{
wek.push_back({v, g});
continue;
}
auto wez=split(v, cut_leq(granice[g]));
wek.push_back({wez.first, g});
v=wez.second;
}
for (int i=1; i<(int)wek.size(); i++)
assert(wek[i].second!=wek[i-1].second);
}
void dfs1(int v, int oj)
{
for (int &i : graf[v])
{
if (i==oj)
{
swap(i, graf[v].back());
graf[v].pop_back();
break;
}
}
minipod[v]=tab[v];
for (int i : graf[v])
{
dfs1(i, v);
minipod[v]=min(minipod[v], minipod[i]);
}
sort(graf[v].begin(), graf[v].end(), mniej);
granice.clear();
for (int i : graf[v])
granice.push_back(minipod[i]);
for (int i : graf[v])
{
ciete[i].clear();
potnij(dp[i], ciete[i]);
}
node *dod=NULL;
int r=graf[v].size();
for (int i=0; i<=r; i++)
sumsuf[i]=0;
for (int i : graf[v])
for (auto j : ciete[i])
sumsuf[j.second]+=daj_sumpra(j.first);
for (int i=r-1; i>=0; i--)
sumsuf[i]+=sumsuf[i+1];
for (int i=0; i<=r; i++)
sumsuf[i]%=mod;
for (int i=0; i<r; i++)
{
ll x=sumsuf[i+1];
for (auto j : ciete[graf[v][i]])
if (j.second>i)
x-=daj_sumpra(j.first);
x%=mod;
x+=mod;
x%=mod;
x=(x*inv(i+2))%mod;
node *now=new node();
now->wag=granice[i];
now->praw=x;
update(now);
dod=merge(dod, now);
}
for (int i=0; i<r; i++)
{
for (auto j : ciete[graf[v][i]])
{
int mni=j.second;
if (i<mni)
mni--;
przemnoz(j.first, inv(mni+1));
}
}
for (int i : graf[v])
for (auto j : ciete[i])
dod=merge_smart(dod, j.first);
auto wez=split(dod, cut_leq(tab[v]));
node *now=new node();
now->wag=tab[v];
now->praw=daj_sumpra(wez.second)+1;
update(now);
usun(wez.second);
dp[v]=merge(wez.first, now);
wyn=(wyn+daj_sumwag(dp[v]))%mod;
}
void test()
{
scanf("%d%d", &n, &korz);
for (int i=1; i<=n; i++)
scanf("%lld", &tab[i]);
for (int i=1; i<=n; i++)
graf[i].clear();
for (int i=1; i<n; i++)
{
int a, b;
scanf("%d%d", &a, &b);
graf[a].push_back(b);
graf[b].push_back(a);
}
wyn=0;
dfs1(korz, 0);
usun(dp[korz]);
printf("%lld\n", wyn);
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
test();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 8ms
memory: 57000kb
input:
4 1 1 1 3 3 3 3 4 3 1 3 2 6 1 5 2 4 1 3 6 1 2 1 6 2 3 2 4 4 5 5 1 5 4 3 2 1 1 2 1 3 3 4 3 5
output:
1 16 34 499122202
result:
ok 4 number(s): "1 16 34 499122202"
Test #2:
score: -100
Memory Limit Exceeded
input:
7 5000 933 23306350 162661794 68618194 666430282 995855733 929210414 295740530 464135554 304211641 725090719 226242817 592655639 936895997 479520010 108891341 598601399 678169271 118406229 394867734 640888099 481066130 606481085 709600400 554804145 179044332 41718098 549318629 400214219 159098456 67...