蒟蒻想起来自己还不会可并堆诶
出题人卡倍增,那么淡定的写了个三进制倍增
#include<cstdio> #include<cstdlib> #include<algorithm> #include<iostream> #include<cmath> #include<limits> #include<cstring> #define V G[p].v using namespace std; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } inline void read(long long &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } inline int dcmp(long double a,long double b){ if (fabs(a-b)<1e-6) return 0; if (a<b) return -1; return 1; } const int N=300005; struct edge{ int u,v; int f,a; int next; }; edge G[N*2]; int head[N],inum; inline void add(int u,int v,int f,int a,int p) { G[p].u=u; G[p].v=v; G[p].f=f; G[p].a=a; G[p].next=head[u]; head[u]=p; } int n,m; int depth[N]; long long h[N]; long double val[N],K[N],B[N]; long double maximum=-1e100; void dfs(int u,long double k,long double b) { val[u]=k*h[u]+b; K[u]=k; B[u]=b; maximum=max(maximum,val[u]); for (int p=head[u];p;p=G[p].next) { depth[V]=depth[u]+1; if (G[p].f==1) dfs(V,k*G[p].a,b); else dfs(V,k,k*G[p].a+b); } } int fat[N][13]; long double maxv[N][13]; inline void Pre() { for (int k=1;k<13;k++) for (int i=1;i<=n;i++) fat[i][k]=fat[fat[fat[i][k-1]][k-1]][k-1]; for (int k=1;k<13;k++) maxv[0][k]=(numeric_limits<long double>::max)(); for (int i=1;i<=n;i++) maxv[i][0]=val[i]; for (int k=1;k<13;k++) for (int i=1;i<=n;i++) maxv[i][k]=max(max(maxv[i][k-1],maxv[fat[i][k-1]][k-1]),maxv[fat[fat[i][k-1]][k-1]][k-1]); } int ans1[N],ans2[N]; int main() { int iv,f,a; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(m); for (int i=1;i<=n;i++) read(h[i]); for (int i=2;i<=n;i++) read(iv),read(f),read(a),add(iv,i,f,a,++inum),fat[i][0]=iv; depth[1]=1; dfs(1,1,0); Pre(); for (int i=1;i<=m;i++) { int S,iC,T; long double C; read(iC); read(S); T=S; C=iC; C=K[S]*C+B[S]; for (int k=12;k>=0;k--) { if (dcmp(max(maxv[T][k],maxv[fat[T][k]][k]),C)<=0) T=fat[fat[T][k]][k]; if (dcmp(maxv[T][k],C)<=0) T=fat[T][k]; } ans1[i]=depth[S]-depth[T]; ans2[T]++; } for (int i=1;i<=n;i++) printf("%d\n",ans2[i]); for (int i=1;i<=m;i++) printf("%d\n",ans1[i]); return 0; }
UPD:random heap 很兹瓷哇
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } inline void read(ll &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } const int N=300005; int ran(){static int x=31253125;x+=(x<<4)+1;return x&65536;} struct node{ node *l,*r; ll key; int idx; ll k,b; void modify(ll _k,ll _b){ key=key*_k+_b; k=k*_k; b=_k*b+_b; } void pushdown(){ if (!(k==1 && b==0)) { if (l) l->modify(k,b); if (r) r->modify(k,b); k=1; b=0; } } }nodes[N]; node *M(node *p,node *q){ if (!p||!q) return (p?p:q); if (p->key>q->key) return M(q,p); p->pushdown(); ran()?p->r=M(p->r,q):p->l=M(p->l,q); return p; } node *root[N]; int n,m; int fa[N],deg[N],depth[N]; ll h[N],f[N],a[N]; int ans1[N],ans2[N]; int S[N]; int Stack[N],pnt; int main() { ll c; int s; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(m); memset(ans2,-1,sizeof(ans2)); for (int i=1;i<=n;i++) read(h[i]); for (int i=2;i<=n;i++) read(fa[i]),read(f[i]),read(a[i]),deg[fa[i]]++,depth[i]=depth[fa[i]]+1; for (int i=1;i<=n;i++) root[i]=NULL; for (int i=1;i<=m;i++) { read(c); read(s); S[i]=s; nodes[i].key=c; nodes[i].l=nodes[i].r=NULL; nodes[i].idx=i; nodes[i].k=1; nodes[i].b=0; root[s]=M(root[s],nodes+i); } for (int i=1;i<=n;i++) if (!deg[i]) Stack[++pnt]=i; while (pnt){ s=Stack[pnt--]; while (root[s] && root[s]->key<h[s]) { ans1[s]++; ans2[root[s]->idx]=depth[S[root[s]->idx]]-depth[s]; root[s]->pushdown(); root[s]=M(root[s]->l,root[s]->r); } if (root[s]) { if (f[s]==0) root[s]->modify(1,a[s]); if (f[s]==1) root[s]->modify(a[s],0); } if (fa[s]) { root[fa[s]]=M(root[fa[s]],root[s]); if (!(--deg[fa[s]])) Stack[++pnt]=fa[s]; } } for (int i=1;i<=m;i++) if (ans2[i]==-1) ans2[i]=depth[S[i]]+1; for (int i=1;i<=n;i++) printf("%d\n",ans1[i]); for (int i=1;i<=m;i++) printf("%d\n",ans2[i]); return 0; }