Advertisement
a53

CFR

a53
May 21st, 2022
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.27 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. ifstream fin("cfr.in");
  4. ofstream fout("cfr.out");
  5. const int kN=1e5;
  6. const int kM=2e5;
  7. const int kLog=17;
  8. const int mod=1e9+7;
  9. int m,f[1+kN],invf[1+kN],sol[1+kN],first[1+kN],tour[1+kM],dep[1+kM],lg2[1+kM],rmq[1+kLog][1+kM];
  10. vector<int>g[1+kN];
  11. struct edge_t
  12. {
  13. int u,v,w;
  14. void read()
  15. {
  16. fin>>u>>v>>w;
  17. }
  18. void addEdge()
  19. {
  20. g[u].emplace_back(v);
  21. g[v].emplace_back(u);
  22. }
  23. bool operator<(const edge_t&rhs) const
  24. {
  25. return w<rhs.w;
  26. }
  27. } edges[kN];
  28.  
  29. struct query_t
  30. {
  31. int m,k,index;
  32. void read()
  33. {
  34. fin>>m>>k;
  35. }
  36. bool operator<(const query_t& rhs) const
  37. {
  38. return m<rhs.m;
  39. }
  40. } q[kN];
  41.  
  42. struct node
  43. {
  44. int sum,cnt;
  45. node operator+(const node& rhs) const
  46. {
  47. return {sum+rhs.sum,cnt+rhs.cnt};
  48. }
  49. } NIL{0,0};
  50.  
  51. struct ST
  52. {
  53. int n;
  54. vector<node>t;
  55. void init(int N)
  56. {
  57. n=N;
  58. int dim=1;
  59. while(dim<n)
  60. dim*=2;
  61. t.assign(dim*2,NIL);
  62. }
  63. void update(int x,int lx,int rx,int pos,int v)
  64. {
  65. if(lx==rx)
  66. {
  67. t[x].sum+=v*lx;
  68. t[x].cnt+=v;
  69. return;
  70. }
  71. int mid=(lx+rx)/2;
  72. if(pos<=mid)
  73. update(x*2,lx,mid,pos,v);
  74. else
  75. update(x*2+1,mid+1,rx,pos,v);
  76. t[x]=t[x*2]+t[x*2+1];
  77. }
  78. void update(int pos, int v)
  79. {
  80. update(1,0,n-1,pos,v);
  81. }
  82. int queryPos(int x, int lx, int rx, int req)
  83. {
  84. if(lx==rx)
  85. {
  86. if(t[x].cnt<req)
  87. return lx;
  88. return lx+1;
  89. }
  90. int mid=(lx+rx)/2;
  91. if(t[x*2+1].cnt<req)
  92. return queryPos(x*2,lx,mid,req-t[x*2+1].cnt);
  93. return queryPos(x*2+1,mid+1,rx,req);
  94. }
  95. node query(int x,int lx,int rx,int st,int dr)
  96. {
  97. if(st<=lx&&rx<=dr)
  98. return t[x];
  99. int mid=(lx+rx)/2;
  100. node left=NIL,right=NIL;
  101. if(st<=mid)
  102. left=query(x*2,lx,mid,st,dr);
  103. if(mid<dr)
  104. right=query(x*2+1,mid+1,rx,st,dr);
  105. return left+right;
  106. }
  107. node query(int st,int dr)
  108. {
  109. return query(1,0,n-1,st,dr);
  110. }
  111. } t;
  112.  
  113. void multSelf(int& x,const int& y)
  114. {
  115. x=(int64_t)x*y%mod;
  116. }
  117.  
  118. int mult(int x,const int& y)
  119. {
  120. multSelf(x,y);
  121. return x;
  122. }
  123.  
  124. int Pow(int x,int n)
  125. {
  126. int ans=1;
  127. while(n!=0)
  128. {
  129. if(n%2==1)
  130. multSelf(ans,x);
  131. multSelf(x,x);
  132. n/=2;
  133. }
  134. return ans;
  135. }
  136.  
  137. int invers(int x)
  138. {
  139. return Pow(x,mod-2);
  140. }
  141.  
  142. void precalc()
  143. {
  144. f[0]=f[1]=1;
  145. for(int i=2;i<=kN;++i)
  146. f[i]=mult(f[i-1],i);
  147. invf[kN]=invers(f[kN]);
  148. for(int i=kN-1;i>=0;--i)
  149. invf[i]=mult(invf[i+1],i+1);
  150. for(int i=2;i<=kM;++i)
  151. lg2[i]=lg2[i/2]+1;
  152. for(int i=1;i<=kM;++i)
  153. rmq[0][i]=i;
  154. }
  155.  
  156. int nck(int n,int k)
  157. {
  158. return mult(f[n],mult(invf[k],invf[n-k]));
  159. }
  160.  
  161. void dfs(int u,int par,int level)
  162. {
  163. tour[++m]=u;
  164. dep[m]=level;
  165. first[u]=m;
  166. for(int v:g[u])
  167. if(v!=par)
  168. dfs(v,u,level+1),tour[++m]=u,dep[m]=level;
  169. }
  170.  
  171. void computeRmq()
  172. {
  173. for(int i=1;(1<<i)<=m;++i)
  174. for(int j=1;j<=m-(1<<i)+1;++j)
  175. {
  176. int l=(1<<(i-1));
  177. rmq[i][j]=rmq[i-1][j];
  178. if(dep[rmq[i-1][j+l]]<dep[rmq[i][j]])
  179. rmq[i][j]=rmq[i-1][j+l];
  180. }
  181. }
  182.  
  183. int lca(int u,int v,bool flag=false)
  184. {
  185. int x=first[u],y=first[v];
  186. if(y<x)
  187. swap(x,y);
  188. int len=y-x+1;
  189. int l=lg2[len];
  190. int index=rmq[l][x];
  191. int shift=len-(1<<l);
  192. if(dep[rmq[l][x+shift]]<dep[index])
  193. index=rmq[l][x+shift];
  194. return tour[index];
  195. }
  196.  
  197. int dist(int u,int v)
  198. {
  199. return dep[first[u]]+dep[first[v]]-2*dep[first[lca(u, v)]];
  200. }
  201.  
  202. struct DSU
  203. {
  204. vector<int> p,sz;
  205. vector<array<int,2>>ends;
  206. DSU(int n)
  207. {
  208. p.resize(n+1);
  209. iota(p.begin(),p.end(),0);
  210. sz.assign(n+1,1);
  211. ends.resize(n+1);
  212. for(int i=1;i<=n;++i)
  213. ends[i]={i,i};
  214. }
  215. int root(int x)
  216. {
  217. if(x==p[x])
  218. return x;
  219. return p[x]=root(p[x]);
  220. }
  221. bool unite(int u,int v)
  222. {
  223. int x=root(u),y=root(v);
  224. if(x==y)
  225. return false;
  226. if(sz[y]<sz[x])
  227. swap(x,y);
  228. array<int,2> nodes;
  229. int dX=dist(ends[x][0],ends[x][1]),dY=dist(ends[y][0],ends[y][1]);
  230. if(dX<dY)
  231. nodes=ends[y];
  232. else
  233. nodes=ends[x];
  234. int best=dist(nodes[0],nodes[1]);
  235. for(const int& st:ends[x])
  236. for (const int& dr : ends[y])
  237. {
  238. int ret = dist(st, dr);
  239. if(best<ret)
  240. best=ret,nodes={st,dr};
  241. }
  242. t.update(dX,-1);
  243. t.update(dY,-1);
  244. t.update(best,1);
  245. ends[y]=nodes;
  246. p[x]=y;
  247. sz[y]+=sz[x];
  248. return true;
  249. }
  250. };
  251.  
  252. void testCase()
  253. {
  254. int task,n;
  255. fin>>task>>n;
  256. for(int i=1;i<=n;++i)
  257. g[i].clear();
  258. for(int i=0;i<n-1;++i)
  259. edges[i].read(),edges[i].addEdge();
  260. sort(edges,edges+n-1);
  261. int Q;
  262. fin>>Q;
  263. for(int i=0;i<Q;++i)
  264. q[i].read(),q[i].k+=1,q[i].index=i;
  265. m=0;
  266. dfs(1,0,0);
  267. computeRmq();
  268. sort(q,q+Q);
  269. DSU dsu(n);
  270. t.init(n);
  271. t.update(0,n);
  272. int ptr=0;
  273. for(int i=0;i<Q;++i)
  274. {
  275. while(ptr<n-1&&edges[ptr].w<=q[i].m)
  276. dsu.unite(edges[ptr].u,edges[ptr].v),ptr+=1;
  277. int minD=t.queryPos(1,0,n-1,q[i].k);
  278. if(minD)
  279. minD-=1;
  280. node ret=t.query(minD,n-1);
  281. int ways=1;
  282. if(ret.cnt<=q[i].k)
  283. q[i].k=ret.cnt;
  284. else
  285. {
  286. node last =t.query(minD,minD);
  287. int rem=ret.cnt-q[i].k;
  288. ret.sum-=rem*minD;
  289. ways=nck(last.cnt,rem);
  290. }
  291. if(task==1)
  292. sol[q[i].index]=ret.sum+q[i].k-1;
  293. else
  294. sol[q[i].index]=ways;
  295. }
  296. for(int i=0;i<Q;++i)
  297. fout<<sol[i]<<'\n';
  298. }
  299.  
  300. int main()
  301. {
  302. precalc();
  303. int tests;
  304. fin>>tests;
  305. for(int tc=0;tc<tests;++tc)
  306. testCase();
  307. return 0;
  308. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement