• 2022.7.31记录


    分散层叠思想:

    将后续信息融入到当前查询中,利用当前查询结果定位后续查询结果

    四毛子思想:

    对数分块,直接打表所有可能面对的情况,最后分块查表即可

    +-1RMQ问题,01矩阵乘法问题,LCA,配合笛卡尔树可以完成任意RMQ问题

    (突然发现自己以前出的一道无结合律的线段树就是四毛子)

    最小差值生成树:

    wssb,排序直接加边,破圈法用当前边代替换上最小边,统计一下存在的边极差即可

    [NOI2014]魔法森林:

    枚举a,把所有小于a的边加入,维护关于b的最小生成树,维护1~n路径上最大的b值

     [BJOI2014]大融合:

    LCT,统计一下删边后两连通块的大小

    [SDOI2017]树点涂色

    LCT+树链剖分

    Access操作时把LCT虚变实的边的下子树权值-1,实变虚的边的下子树的权值+1

    本质上是由LCT确定维护的区间,然后在dfs序的线段树上维护最大值

    一个防止findroot的方法,在LCT中维护dep最小的点的编号

    代码:(老了,首先是fir[u]写成了fir[p],调了一个小时,然后是线段树懒标记下传写错,又调了一个小时,再是rot少写了更新z节点的语句,又调了半个小时,麻中麻)

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. inline int gi()
    6. {
    7. char c;int num=0,flg=1;
    8. while((c=getchar())<'0'||c>'9')if(c=='-')flg=-1;
    9. while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
    10. return num*flg;
    11. }
    12. #define N 100005
    13. int to[2*N],nxt[2*N],fir[N],cnt;
    14. void adde(int a,int b)
    15. {
    16. to[++cnt]=b;nxt[cnt]=fir[a];fir[a]=cnt;
    17. }
    18. int siz[N],son[N],top[N],fa[N],dep[N];
    19. int dfn[N],num[N],dc;
    20. void dfs1(int u,int f)
    21. {
    22. fa[u]=f;
    23. dep[u]=dep[f]+1;
    24. siz[u]=1;
    25. for(int v,p=fir[u];p;p=nxt[p]){
    26. if((v=to[p])!=f){
    27. dfs1(v,u);
    28. siz[u]+=siz[v];
    29. if(siz[son[u]]
    30. son[u]=v;
    31. }
    32. }
    33. }
    34. void dfs2(int u)
    35. {
    36. dfn[u]=++dc;num[dc]=u;
    37. if(son[u]){
    38. top[son[u]]=top[u];
    39. dfs2(son[u]);
    40. }
    41. for(int v,p=fir[u];p;p=nxt[p]){
    42. v=to[p];
    43. if(v!=son[u]&&v!=fa[u]){
    44. top[v]=v;
    45. dfs2(v);
    46. }
    47. }
    48. }
    49. int LCA(int u,int v)
    50. {
    51. while(top[u]!=top[v]){
    52. if(dep[top[u]]
    53. swap(u,v);
    54. u=fa[top[u]];
    55. }
    56. return dep[u]
    57. }
    58. struct node{
    59. int l,r,mx,la;
    60. }a[4*N];
    61. void pushup(int i)
    62. {
    63. a[i].mx=max(a[i<<1].mx,a[i<<1|1].mx);
    64. }
    65. void build(int i,int l,int r)
    66. {
    67. a[i].l=l;a[i].r=r;
    68. if(l==r){
    69. a[i].mx=dep[num[l]];
    70. return;
    71. }
    72. int mid=(l+r)>>1;
    73. build(i<<1,l,mid);
    74. build(i<<1|1,mid+1,r);
    75. pushup(i);
    76. }
    77. void pushdown(int i)
    78. {
    79. if(a[i].l==a[i].r)return;
    80. if(a[i].la){
    81. a[i<<1].mx+=a[i].la;
    82. a[i<<1|1].mx+=a[i].la;
    83. a[i<<1].la+=a[i].la;
    84. a[i<<1|1].la+=a[i].la;
    85. a[i].la=0;
    86. }
    87. }
    88. void update(int i,int l,int r,int k)
    89. {
    90. if(a[i].l>r||a[i].rreturn;
    91. pushdown(i);
    92. if(l<=a[i].l&&a[i].r<=r){
    93. a[i].mx+=k;
    94. a[i].la+=k;
    95. return;
    96. }
    97. update(i<<1,l,r,k);
    98. update(i<<1|1,l,r,k);
    99. pushup(i);
    100. }
    101. int query(int i,int l,int r)
    102. {
    103. if(a[i].l>r||a[i].rreturn 0;
    104. pushdown(i);
    105. if(l<=a[i].l&&a[i].r<=r)
    106. return a[i].mx;
    107. return max(query(i<<1,l,r),query(i<<1|1,l,r));
    108. }
    109. namespace LCT{
    110. int ch[N][2],fa[N],mipos[N];
    111. void pushup(int x)
    112. {
    113. mipos[x]=x;
    114. if(ch[x][0]&&dep[mipos[ch[x][0]]]
    115. mipos[x]=mipos[ch[x][0]];
    116. if(ch[x][1]&&dep[mipos[ch[x][1]]]
    117. mipos[x]=mipos[ch[x][1]];
    118. }
    119. bool pdc(int x){return ch[fa[x]][1]==x;}
    120. bool pdr(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
    121. void rot(int x)
    122. {
    123. int y=fa[x],z=fa[y];
    124. bool flg=pdc(x);
    125. if(!pdr(y)) ch[z][pdc(y)]=x;
    126. if(ch[y][flg]=ch[x][flg^1])
    127. fa[ch[y][flg]]=y;
    128. ch[x][flg^1]=y;
    129. fa[y]=x;fa[x]=z;
    130. pushup(y);pushup(x);
    131. }
    132. void splay(int x,int y)
    133. {
    134. for(;!pdr(x);rot(x))
    135. if(!pdr(fa[x]))
    136. rot(pdc(x)==pdc(fa[x])?fa[x]:x);
    137. }
    138. int findroot(int x)
    139. {
    140. while(ch[x][0])x=ch[x][0];
    141. return x;
    142. }
    143. void Access(int x)
    144. {
    145. int tmp=0;
    146. for(;x;x=fa[x]){
    147. splay(x,0);
    148. if(ch[x][1]){
    149. int rt=mipos[ch[x][1]];
    150. //int rt=findroot(ch[x][1]);
    151. update(1,dfn[rt],dfn[rt]+siz[rt]-1,1);
    152. }
    153. if(tmp){
    154. int rt=mipos[tmp];
    155. //int rt=findroot(tmp);
    156. update(1,dfn[rt],dfn[rt]+siz[rt]-1,-1);
    157. }
    158. ch[x][1]=tmp;
    159. pushup(x);
    160. tmp=x;
    161. }
    162. }
    163. }
    164. int main()
    165. {
    166. int n,m,x,y,i,op;
    167. n=gi();m=gi();
    168. for(i=1;i
    169. x=gi();y=gi();
    170. adde(x,y);adde(y,x);
    171. }
    172. dfs1(1,0);
    173. top[1]=1;
    174. dfs2(1);
    175. build(1,1,n);
    176. for(i=1;i<=n;i++)
    177. LCT::fa[i]=fa[i];
    178. while(m--){
    179. op=gi();
    180. if(op==1){
    181. x=gi();
    182. LCT::Access(x);
    183. }
    184. else if(op==2){
    185. x=gi();y=gi();
    186. int lca=LCA(x,y);
    187. int ans=query(1,dfn[x],dfn[x])+query(1,dfn[y],dfn[y])-2*query(1,dfn[lca],dfn[lca])+1;
    188. printf("%d\n",ans);
    189. }
    190. else{
    191. x=gi();
    192. printf("%d\n",query(1,dfn[x],dfn[x]+siz[x]-1));
    193. }
    194. }
    195. }

  • 相关阅读:
    立创EDA仿真入门2 实战全桥整流
    Day41—— 343. 整数拆分 96.不同的二叉搜索树 (动规)
    「面经分享」小米java岗二面面经,已拿offer
    Cookie的使用(基于js-cookie插件)
    聊一聊对“事务”的理解
    【vue3】12.跟着官网学习vue3-侦听器,watch方法
    基于多模态知识图谱的多模态推理-MR-MKG
    centos 8 yum源不能使用问题
    最小可用产品MVP,投石问路
    Oracle数据库 on duplicate key update功能
  • 原文地址:https://blog.csdn.net/C20180602_csq/article/details/126091627