题目

描述

​ 给出一颗树,定义根节点1的深度为1,其他点深度为父亲深度+1;

​ 如下定义一个点的点权:

​ 1.叶子:为其编号;2.奇数深度:为其儿子编号最大值;3.偶数深度:为其儿子编号最小值;

​ 对于一个叶子集合 \(S\) ,你可以修改 $w_i \to w_i \pm C ,i \in S $ , 称使得根权值改变的最小\(C\)为\(S\)的稳定度;(如果无论如何根都不变规定稳定度为\(n\))

​ 询问稳定度为 \(i \in [L,R]\) 的有多少个,对每个 \(i\) 依次输出;

范围

​ $2 \le n \le 2 \times 10^5 \ , \ 1 \le L \le R \le n $

题解

  • 由于点权互不相同,所以一定可以找到一条到某个叶子的链:链上的值都是根节点的值,记这个链为\(key\) ,并且顶点的权值改变的充要条件是\(key\)上某个点改变。考虑统计不改变的情况,对\(key\)上每个点分奇偶做一个 \(dp\) 再相乘,可以求出不变方案数,获得了一个 \(O(n(R-L))\) 的算法。

  • 从小到大考虑 \(C\) ,每个叶子的初始值只会改变一次,用\(ddp\)维护即可。注意由于系数有0需要特判一下;

    1. #include<bits/stdc++.h>
    2. #define mod 998244353
    3. #define ll long long
    4. #define ls (k<<1)
    5. #define rs (k<<1|1)
    6. #define mk make_pair
    7. #define pir pair<int,int>
    8. #define fi first
    9. #define se second
    10. #define il inline
    11. #define rg register
    12. using namespace std;
    13. const int N=200010;
    14. int n,L,R,o=1,hd[N],d[N],f[N],g[N],col[N],dep[N],lf[N],id[N];
    15. int fa[N],sz[N],sn[N],st[N],tp[N],dn[N],idx,now,ans[N],cnt,tot;
    16. struct Edge{int v,nt;}E[N<<1];
    17. struct data{
    18. int a,b;
    19. il data operator +(const data&A)const{
    20. data ret;
    21. ret.a=(ll)a*A.a%mod;
    22. ret.b=((ll)A.b*a%mod+b)%mod;
    23. return ret;
    24. }//维护ax+b的迭代;
    25. }tr[N<<2];
    26. il int pw(int x,int y){
    27. int re=1;x%=mod;
    28. while(y){
    29. if(y&1)re=(ll)re*x%mod;
    30. y>>=1;x=(ll)x*x%mod;
    31. }
    32. return re;
    33. }
    34. pir a[N];int b[N];
    35. il int val(pir A){return A.se?0:A.fi;}
    36. il pir operator +(pir A,int B){if(!B)A.se++;else A.fi=(ll)A.fi*B%mod;return A;}
    37. il pir operator -(pir A,int B){if(!B)A.se--;else A.fi=(ll)A.fi*pw(B,mod-2)%mod;return A;}
    38. //用来处理ax+b系数a为0的情况;
    39. il char gc(){
    40. static char*p1,*p2,s[1000000];
    41. if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
    42. return(p1==p2)?EOF:*p1++;
    43. }
    44. il int rd(){
    45. int x=0;char c=gc();
    46. while(c<'0'||c>'9')c=gc();
    47. while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
    48. return x;
    49. }
    50. il void adde(int u,int v){
    51. d[u]++,d[v]++;
    52. E[o]=(Edge){v,hd[u]};hd[u]=o++;
    53. E[o]=(Edge){u,hd[v]};hd[v]=o++;
    54. }
    55. il void Min(int&x,int y){if(x>y)x=y;}
    56. il void Max(int&x,int y){if(x<y)x=y;}
    57. void dfs_pre(int u,int F){
    58. dep[u]=dep[fa[u]=F]+1;sz[u]=1;
    59. if(u!=1&&d[u]==1){lf[u]=2;f[u]=dn[u]=u;return;}
    60. lf[u]=1;f[u]=dep[u]&1?0:n;
    61. for(rg int i=hd[u];i;i=E[i].nt){
    62. int v=E[i].v;
    63. if(v==F)continue;
    64. dfs_pre(v,u);
    65. sz[u]+=sz[v];lf[u]=(ll)lf[u]*lf[v]%mod;
    66. if(sz[sn[u]]<sz[v])sn[u]=v,dn[u]=dn[v];
    67. if(dep[u]&1)Max(f[u],f[v]);else Min(f[u],f[v]);
    68. }
    69. }
    70. //以下为朴素dp部分:
    71. //***************************************
    72. void dfs_mn(int u,int T){
    73. st[++idx]=u;id[u]=idx;
    74. tp[u]=T;g[u]=1;col[u]=1;
    75. if(u!=1&&d[u]==1){a[u]=mk(0,0),b[u]=g[u]=(u<=f[1])<<1;return;}
    76. if(dep[u]&1){
    77. a[u]=mk(1,0);b[u]=0;
    78. dfs_mn(sn[u],T);
    79. g[u]=(ll)g[u]*g[sn[u]]%mod;
    80. for(rg int i=hd[u];i;i=E[i].nt){
    81. int v=E[i].v;
    82. if(v==fa[u]||v==sn[u])continue;
    83. dfs_mn(v,v);
    84. g[u]=(ll)g[u]*g[v]%mod;
    85. a[u]=a[u]+g[v]%mod;
    86. }
    87. }else{
    88. a[u]=mk(1,0);
    89. dfs_mn(sn[u],T);
    90. g[u]=(ll)g[u]*(lf[sn[u]]-g[sn[u]]+mod)%mod;
    91. for(rg int i=hd[u];i;i=E[i].nt){
    92. int v=E[i].v;
    93. if(v==fa[u]||v==sn[u])continue;
    94. dfs_mn(v,v);
    95. g[u]=(ll)g[u]*(lf[v]-g[v]+mod)%mod;
    96. a[u]=a[u]+((lf[v]-g[v]+mod)%mod);
    97. }
    98. g[u]=(lf[u]-g[u]+mod)%mod;
    99. b[u]=(lf[u]-(ll)val(a[u])*lf[sn[u]]%mod+mod)%mod;
    100. }
    101. }
    102. void dfs_mx(int u,int T){
    103. st[++idx]=u;id[u]=idx;
    104. tp[u]=T;g[u]=1;col[u]=2;
    105. if(u!=1&&d[u]==1){a[u]=mk(0,0),b[u]=g[u]=(u>=f[1])<<1;return;}
    106. if(dep[u]&1){
    107. a[u]=mk(1,0);
    108. dfs_mx(sn[u],T);
    109. g[u]=(ll)g[u]*(lf[sn[u]]-g[sn[u]]+mod)%mod;
    110. for(rg int i=hd[u];i;i=E[i].nt){
    111. int v=E[i].v;
    112. if(v==fa[u]||v==sn[u])continue;
    113. dfs_mx(v,v);
    114. g[u]=(ll)g[u]*(lf[v]-g[v]+mod)%mod;
    115. a[u]=a[u]+(lf[v]-g[v]+mod)%mod;
    116. }
    117. g[u]=(lf[u]-g[u]+mod)%mod;
    118. b[u]=(lf[u]-(ll)val(a[u])*lf[sn[u]]%mod+mod)%mod;
    119. }else{
    120. a[u]=mk(1,0);b[u]=0;
    121. dfs_mx(sn[u],T);
    122. g[u]=(ll)g[u]*g[sn[u]]%mod;
    123. for(rg int i=hd[u];i;i=E[i].nt){
    124. int v=E[i].v;
    125. if(v==fa[u]||v==sn[u])continue;
    126. dfs_mx(v,v);
    127. g[u]=(ll)g[u]*g[v]%mod;
    128. a[u]=a[u]+g[v]%mod;
    129. }
    130. }
    131. }
    132. void dfs_key(int u){
    133. for(rg int i=hd[u];i;i=E[i].nt){
    134. int v=E[i].v;
    135. if(v==fa[u])continue;
    136. if(f[u]==f[v]){dfs_key(v);continue;}
    137. if(dep[u]&1)dfs_mn(v,v);else dfs_mx(v,v);
    138. now=(ll)now*g[v]%mod;
    139. }
    140. }
    141. //******************************************
    142. il void pushup(int k){tr[k]=tr[ls]+tr[rs];}
    143. void build(int k,int l,int r){
    144. if(l==r){tr[k]=(data){val(a[st[l]]),b[st[l]]};return;}
    145. int mid=l+r>>1;
    146. build(ls,l,mid);
    147. build(rs,mid+1,r);
    148. pushup(k);
    149. }
    150. void update(int k,int l,int r,int x){
    151. /*{
    152. cnt++;
    153. }*/
    154. if(l==r){tr[k]=(data){val(a[st[l]]),b[st[l]]};return;}
    155. int mid=l+r>>1;
    156. if(x<=mid)update(ls,l,mid,x);
    157. else update(rs,mid+1,r,x);
    158. pushup(k);
    159. }
    160. data query(int k,int l,int r,int x,int y){
    161. /*{
    162. cnt++;
    163. }*/
    164. if(l==x&&r==y)return tr[k];
    165. int mid=l+r>>1;
    166. if(y<=mid)return query(ls,l,mid,x,y);
    167. else if(x>mid)return query(rs,mid+1,r,x,y);
    168. else return query(ls,l,mid,x,mid)+query(rs,mid+1,r,mid+1,y);
    169. }
    170. il void Update_mn(int u){
    171. int tmp,tu,du,v;
    172. a[u]=mk(0,0),b[u]=1;
    173. while(1){
    174. tot++;
    175. tu=tp[u];du=dn[u];
    176. update(1,1,n,id[u]);
    177. tmp=g[tu],g[tu]=query(1,1,n,id[tu],id[du]).b;
    178. v=tu,u=fa[tu];
    179. if(!col[u])break;
    180. if(dep[u]&1){
    181. a[u]=a[u]-tmp+g[v];
    182. b[u]=0;
    183. }else {
    184. a[u]=a[u]-(lf[v]-tmp+mod)%mod+(lf[v]-g[v]+mod)%mod;
    185. b[u]=(lf[u]-(ll)lf[sn[u]]*val(a[u])%mod+mod)%mod;
    186. }
    187. }
    188. now=(ll)now*pw(tmp,mod-2)%mod*g[v]%mod;
    189. }
    190. il void Update_mx(int u){
    191. int tmp,tu,du,v;
    192. a[u]=mk(0,0),b[u]=1;
    193. while(1){
    194. tot++;
    195. tu=tp[u];du=dn[u];
    196. update(1,1,n,id[u]);
    197. tmp=g[tu],g[tu]=query(1,1,n,id[tu],id[du]).b;
    198. v=tu,u=fa[tu];
    199. if(!col[u])break;
    200. if(dep[u]&1){
    201. a[u]=a[u]-(lf[v]-tmp+mod)%mod+(lf[v]-g[v]+mod)%mod;
    202. b[u]=(lf[u]-(ll)lf[sn[u]]*val(a[u])%mod+mod)%mod;
    203. }else{
    204. a[u]=a[u]-tmp+g[v];
    205. b[u]=0;
    206. }
    207. }
    208. now=(ll)now*pw(tmp,mod-2)%mod*g[v]%mod;
    209. }
    210. char ps[1000000],*pp=ps;
    211. void push(char x){
    212. if(pp==ps+1000000)fwrite(ps,1,1000000,stdout),pp=ps;
    213. *pp++=x;
    214. }
    215. void write(int x){
    216. if(!x){push('0');push(' ');return;}
    217. static int sta[20],top;
    218. while(x)sta[++top]=x%10,x/=10;
    219. while(top)push(sta[top--]^'0');
    220. push(' ');
    221. }
    222. void flush(){fwrite(ps,1,pp-ps,stdout);}
    223. int main(){
    224. //freopen("minimax.in","r",stdin);
    225. //freopen("minimax.out","w",stdout);
    226. n=rd();L=rd();R=rd();
    227. for(rg int i=1;i<n;++i)adde(rd(),rd());
    228. dfs_pre(1,0);
    229. now=1;dfs_key(1);
    230. ans[1]=(lf[1]-now+mod)%mod;
    231. build(1,1,n);
    232. //cerr<<fixed<<setprecision(2)<<1.0*clock()/CLOCKS_PER_SEC<<endl;
    233. for(rg int i=2,j1=f[1]-1,j2=f[1]+1;i<n;++i){
    234. while(j1>=1&&j1+i>f[1]){if(d[j1]==1&&col[j1]==1)Update_mn(j1);j1--;}
    235. while(j2<=n&&j2-i<f[1]){if(d[j2]==1&&col[j2]==2)Update_mx(j2);j2++;}
    236. ans[i]=(lf[1]-now+mod)%mod;
    237. /*if(i==1000){
    238. write(cnt);
    239. write(tot);
    240. break;
    241. }*/
    242. // cerr<<fixed<<setprecision(2)<<1.0*clock()/CLOCKS_PER_SEC<<endl;
    243. }
    244. ans[n]=lf[1]-1;
    245. for(rg int i=n;i;--i)ans[i]=(ans[i]-ans[i-1]+mod)%mod;
    246. for(rg int i=L;i<=R;++i)write(ans[i]);//printf("%d ",ans[i]);
    247. flush();
    248. //printf("%.2lf\n",1.0*clock()/CLOCKS_PER_SEC);
    249. //cerr<<fixed<<setprecision(2)<<1.0*clock()/CLOCKS_PER_SEC<<endl;
    250. return 0;
    251. }

【loj3044】【zjoi2019】Minimax的更多相关文章

  1. 【LOJ】#3044. 「ZJOI2019」Minimax 搜索

    LOJ#3044. 「ZJOI2019」Minimax 搜索 一个菜鸡的50pts暴力 设\(dp[u][j]\)表示\(u\)用\(j\)次操作能使得\(u\)的大小改变的方案数 设每个点的初始答案 ...

  2. 【疯狂造轮子-iOS】JSON转Model系列之二

    [疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...

  3. 【疯狂造轮子-iOS】JSON转Model系列之一

    [疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...

  4. 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付

    前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...

  5. 【AutoMapper官方文档】DTO与Domin Model相互转换(上)

    写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...

  6. 【Win 10 应用开发】应用预启动

    所谓预启动,其实你一看那名字就知道是啥意思了,这是直接译,也找不到比这个叫法更简练的词了.在系统资源允许的情况下(比如电池电量充足,有足够的内存空间),系统会把用户常用的应用程序在后台启动,但不会显示 ...

  7. 【Win 10 应用开发】启动远程设备上的应用

    这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...

  8. 【开源】分享2011-2015年全国城市历史天气数据库【Sqlite+C#访问程序】

    由于个人研究需要,需要采集天气历史数据,前一篇文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子),介绍了基本的采集思路和核心代码,经过1个星期的采集,历史数据库 ...

  9. 【原创分享·微信支付】C# MVC 微信支付教程系列之现金红包

            微信支付教程系列之现金红包           最近最弄这个微信支付的功能,然后扫码.公众号支付,这些都做了,闲着无聊,就看了看微信支付的其他功能,发现还有一个叫“现金红包”的玩意,想 ...

  10. 【原创分享·微信支付】 C# MVC 微信支付教程系列之扫码支付

    微信支付教程系列之扫码支付                  今天,我们来一起探讨一下这个微信扫码支付.何为扫码支付呢?这里面,扫的码就是二维码了,就是我们经常扫一扫的那种二维码图片,例如,我们自己添 ...

随机推荐

  1. 【JVM.12】线程安全与锁优化

    一.概述 面向过程的编程思想极大地提升了现代软件开发的生产效率和软件可以达到的规模,但是现实世界与计算机世界之间不可避免地存在一些差异,本节就如何保证并发的正确性和如何实现线程安全讲起. 二.线程安全 ...

  2. IDEA启动服务阻塞,断点过程十分慢的问题

    使用debug无法启动项目但是使用run就可以启动程序,而且启动比以前的debug模式快的多 原因: 启动不了的原因是在项目中的方法上打了断点,导致项目无法继续编译 取消方法断点就可以了 在idea官 ...

  3. 对spring cloud config的一点理解

    以下部分纯属个人理解,但是结果都是经过demo验证. 一.spring cloud config介绍 spring cloud是spring家族中的一个微服务工具包,其中包含了很多微服务的工具.偏向于 ...

  4. PAT 1047 编程团体赛

    https://pintia.cn/problem-sets/994805260223102976/problems/994805277163896832 编程团体赛的规则为:每个参赛队由若干队员组成 ...

  5. SQLSERVER最简单的同名数据库恢复过程.

    一. 冷备份恢复 1. net stop mssqlserver # 如果是安装的默认数据库实例 关闭 sqlserver的数据库 2. copy sqlserver的数据文件 主要是mdf 数据文件 ...

  6. 判断Excel版本信息

    可以通过获取application对应的Version属性获取当前打开的Excel的版本信息(Application.Version).

  7. OneZero第七周第一次站立会议(2016.5.9)

    1. 时间: 12:15--12:25  共计10分钟. 2. 成员: X 夏一鸣 * 组长 (博客:http://www.cnblogs.com/xiaym896/), G 郭又铭 (博客:http ...

  8. OneZero产品视频

    产品视频地址:http://v.youku.com/v_show/id_XMTU1MDMwOTk2OA==.html

  9. C# PictureBox控件畫圖

    PictureBox的正方向: BitMap初始化: Bitmap bt = new Bitmap(Width,Height);      Graphics gdi = Graphics.FromIm ...

  10. selenium之截图

    selenium支持对当前页面保存截图,使用方法: driver.get_screenshot_as_file(file_path) 代码举例: ...... def get_screenshot(d ...