Test instructions: BC Round 74
Analysis:
Refer to the common use of heap maintenance dictionary order of the smallest topological sequence, with a data structure to maintain the degree of less than equal to k all points, each find the smallest number, and the corresponding reduction of K .
This data structure can be used to create a line segment tree for each node[l,R] maintain the minimum entry for all nodes from L l to RR, only two points in the segment tree are required when querying.
< Span class= "Strut bottom" >< Span class= "Katex-mathml" > find the smallest x satisfies the in-degree less than or equal to k .
Complexity O((n+m)logn)
#include <iostream>#include<cstdio>#include<vector>#include<cstring>#include<queue>#include<cmath>using namespaceStd;typedefLong LongLL;Const intmod=1e9+7;Const intinf=0x3f3f3f3f;Const intn=1e5+5;intd[n],o[n<<2],head[n],p;structedge{intV,next;} Edge[n*2];voidAddintUintv) {EDGE[P].V=v; Edge[p].next=Head[u]; Head[u]=p++;}voidPushup (intRT) {O[rt]=min (o[rt*2],o[rt*2+1]);}voidBuildintRtintLintR) { if(l==R) {O[rt]=D[l]; return; } intMid= (l+r) >>1; Build (Rt*2, L,mid); Build (Rt*2+1, mid+1, R); Pushup (RT);}voidUpdateintRtintLintRintPOS) { if(l==R) {O[rt]=D[l]; return; } intMid= (l+r) >>1; if(pos<=mid) Update (rt*2, L,mid,pos); ElseUpdate (rt*2+1, mid+1, R,pos); Pushup (RT);}intQueryintRtintLintRintc) { if(l==R)returnl; intMid= (l+r) >>1; if(o[rt*2]<=C)returnQuery (rt*2, L,mid,c); Else returnQuery (rt*2+1, mid+1, r,c);}intMain () {intt,n,m,k; scanf ("%d", &T); while(t--) {scanf ("%d%d%d",&n,&m,&k); memset (Head,-1,sizeof(head)); memset (d,0,sizeof(d)); P=0; for(intI=0; i<m;++i) {intu,v; scanf ("%d%d",&u,&v); Add (U,V); ++D[v]; } Build (1,1, N); LL ans=0; for(intI=1; i<=n;++i) {LL x=query (1,1, n,k), y=i; Ans= (ans+x*y%mod)%MoD; K-=D[x]; D[X]=INF; Update (1,1, n,x); for(intj=head[x];~j;j=Edge[j].next) { intv=edge[j].v; if(D[v]==inf)Continue; --D[v]; Update (1,1, n,v); }} printf ("%i64d\n", ans); } return 0;}View Code
HDU 5638 Toposort line tree + greedy