妈妈呀吓死我了再也不敢写斜堆了。。。。。。。。。。斜堆跑了9秒多,差点超时(我怀疑单点早超时了)
其实斜堆和左偏树比起来就少了一个变量和一行代码。
还是老老实实写左偏树算了。
这题嘛,维护若干个堆,堆里面是好多好多骑士,然后DFS一下,每次DFS的时候把每个点的子节点都merge过来,然后DFS完一个节点就把到达这个节点的渣渣骑士都干掉,顺便看一下他们经过了多少城池,同时把该节点(城池)的战绩更新一下。
这题过得我好虚啊……
#include<iostream> #include<cstdio> #include<cstring> #include<cctype> #define lc(x) heap[x].lc #define rc(x) heap[x].rc #define v(x) heap[x].v #define a(x) heap[x].a #define m(x) heap[x].m #define d(x) heap[x].d using namespace std; const int N=300000+10; typedef long long ll; template<class T>void read(T& x){ static char c; static bool f; for(f=0;c=getchar(),!isdigit(c);)if(c=='-')f=1; for(x=0;isdigit(c);c=getchar())x=x*10+c-'0'; if(f)x=-x; } struct Node{ int lc,rc,d; ll v,a,m; }heap[N]; void add_tag(int x,ll mul,ll add){ if(!x)return; m(x)*=mul; a(x)=a(x)*mul+add; v(x)=v(x)*mul+add; } void down(int x){ add_tag(lc(x),m(x),a(x));add_tag(rc(x),m(x),a(x)); m(x)=1;a(x)=0; } int merge(int x,int y){ if(!x||!y)return x+y; if(v(x)>v(y))swap(x,y); down(x);down(y); rc(x)=merge(rc(x),y); if(d(rc(x))>d(lc(x)))swap(lc(x),rc(x)); d(x)=d(rc(x))+1; return x; } struct Edge{int to,next;}e[N]; int head[N],cnt; void ins(int u,int v){ e[++cnt]=(Edge){v,head[u]};head[u]=cnt; } int die[N],get[N],fa[N],root[N],d[N],c[N]; ll def[N],mul[N],add[N]; void dfs(int u){ die[u]=0; for(int i=head[u];i;i=e[i].next){ int v=e[i].to; d[v]=d[u]+1; dfs(v); add_tag(root[v],mul[v],add[v]); root[u]=merge(root[u],root[v]); } while(root[u]&&v(root[u])<def[u]){ down(root[u]); get[root[u]]=d[c[root[u]]]-d[u]; root[u]=merge(lc(root[u]),rc(root[u])); die[u]++; } } int main(){ int n,m;read(n);read(m); for(int i=1;i<=n;i++)read(def[i]); int kind;ll tmp; for(int i=2;i<=n;i++){ read(fa[i]);read(kind);read(tmp); if(kind)mul[i]=tmp,add[i]=0; else mul[i]=1,add[i]=tmp; ins(fa[i],i); } for(int i=1;i<=m;i++){ read(v(i));read(c[i]); m(i)=1; root[c[i]]=merge(root[c[i]],i); } dfs(1); while(root[1]){ get[root[1]]=d[c[root[1]]]-d[1]+1; root[1]=merge(lc(root[1]),rc(root[1])); } for(int i=1;i<=n;i++)printf("%d\n",die[i]); for(int i=1;i<=m;i++)printf("%d\n",get[i]); return 0; }