树链剖分:(来源:树的统计)

#include<bits/stdc++.h>
#define rint register int
using namespace std;
inline void read(int &A)
{
A=;int B=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')B=-;ch=getchar();}
while(ch>=''&&ch<=''){A=(A<<)+(A<<)+ch-'';ch=getchar();}
A=A*B;return ;
}
int n,q,v[],w[],nxt[],first[],tot;
int f[],d[],siz[],son[];
int id[],rk[],cnt,tp[],ans;
char ch[];
struct node{int k,mx;}t[<<];
inline void build_line(int uu,int vv)
{
v[++tot]=vv,nxt[tot]=first[uu];
first[uu]=tot;
}
inline void dfs(int x,int fa,int dep)
{
f[x]=fa,d[x]=dep,siz[x]=;
for(rint i=first[x];i;i=nxt[i])
{
int y=v[i];if(y==fa)continue;
dfs(y,x,dep+);siz[x]+=siz[y];
if(siz[y]>siz[son[x]])son[x]=y;
}
return ;
}
inline void Dfs(int x,int t)
{
tp[x]=t,id[x]=++cnt,rk[cnt]=x;
if(!son[x])return ;Dfs(son[x],t);
for(rint i=first[x];i;i=nxt[i])
if(v[i]!=son[x]&&v[i]!=f[x])
Dfs(v[i],v[i]);
return ;
}
inline void update(int k)
{
t[k].k=t[k<<].k+t[k<<|].k;
t[k].mx=max(t[k<<].mx,t[k<<|].mx);
return ;
}
inline void build(int k,int l,int r)
{
if(l==r){t[k].k=t[k].mx=w[rk[l]];return ;}
int mid=(l+r)>>;
build(k<<,l,mid);build(k<<|,mid+,r);
update(k);return ;
}
inline int Qsum(int k,int l,int r,int L,int R)
{
if(L<=l&&r<=R)return t[k].k;
int mid=(l+r)>>,res=;
if(L<=mid)res+=Qsum(k<<,l,mid,L,R);
if(R>mid)res+=Qsum(k<<|,mid+,r,L,R);
return res;
}
inline int Qmax(int k,int l,int r,int L,int R)
{
if(L<=l&&r<=R)return t[k].mx;
int mid=(l+r)>>,res=-0x7fffffff;
if(L<=mid)res=max(res,Qmax(k<<,l,mid,L,R));
if(R>mid)res=max(res,Qmax(k<<|,mid+,r,L,R));
return res;
}
inline void change(int k,int l,int r,int p,int dat)
{
if(l==r){t[k].k=t[k].mx=dat;return ;}
int mid=(l+r)>>;
if(p<=mid)change(k<<,l,mid,p,dat);
else change(k<<|,mid+,r,p,dat);
update(k);return ;
}
inline int get_sum(int x,int y)
{
int Sum=,fx=tp[x],fy=tp[y];
while(fx!=fy)
{
if(d[fx]>=d[fy])
{
Sum+=Qsum(,,n,id[fx],id[x]);
x=f[fx],fx=tp[x];
}
else
{
Sum+=Qsum(,,n,id[fy],id[y]);
y=f[fy],fy=tp[y];
}
}
if(id[x]<=id[y])Sum+=Qsum(,,n,id[x],id[y]);
else Sum+=Qsum(,,n,id[y],id[x]);
return Sum;
}
inline int get_max(int x,int y)
{
int Max=-0x7fffffff,fx=tp[x],fy=tp[y];
while(fx!=fy)
{
if(d[fx]>=d[fy])
{
Max=max(Max,Qmax(,,n,id[fx],id[x]));
x=f[fx],fx=tp[x];
}
else
{
Max=max(Max,Qmax(,,n,id[fy],id[y]));
y=f[fy],fy=tp[y];
}
}
if(id[x]<=id[y])Max=max(Max,Qmax(,,n,id[x],id[y]));
else Max=max(Max,Qmax(,,n,id[y],id[x]));
return Max;
}
int main()
{
// freopen("count1.in","r",stdin);
// freopen("my.out","w",stdout);
read(n);
for(rint i=,ST,EN;i<n;++i)
{
read(ST),read(EN);
build_line(ST,EN);
build_line(EN,ST);
}
for(rint i=;i<=n;++i)read(w[i]);
dfs(,,);Dfs(,);build(,,n);
read(q);
for(rint i=,uu,vv;i<=q;++i)
{
scanf("%s",ch);
if(ch[]=='C')
{
read(uu),read(vv);
change(,,n,id[uu],vv);
}
else
{
ans=;read(uu),read(vv);
if(ch[]=='M')ans=get_max(uu,vv);
else ans=get_sum(uu,vv);
printf("%d\n",ans);
}
}
}

树链剖分模板

tarjan点双

inline void tarjan(int x)
{
dfn[x]=low[x]=++cnt;s.push(x);
if(x==root && firsty[x]==)
{
dcc[++totq].clear();
dcc[totq].push_back(x);
return ;
}
int flag=;
for(rint i=firsty[x];i;i=edge[i].nxt)
{
int y=edge[i].v;
if(!dfn[y])
{
tarjan(y);low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x])
{
flag++;
if(x!=root||flag>)cut[x]=true;
totq++;int z;
dcc[totq].clear();
do{
z=s.top();s.pop();
dcc[totq].push_back(z);
}while(z!=y);
dcc[totq].push_back(x);
}
}
else low[x]=min(low[x],dfn[y]);
}
}

tarjan点双模板

二分图匹配(带注释)

int point(int u)//这个函数的作用是寻找增广路和更新cx,xy数组,如果找到了增广路,函数返回1,找不到,函数返回0。
{
for(int v=;v<=ny;v++)//依次遍历右边的所有顶点
{
if(e[u][v]&&!visited[v])//条件一:左边的u顶点和右边的v顶点有连通边,条件二:右边的v顶点在没有被访问过,这两个条件必须同时满足
{
visited[v]=;//将v顶点标记为访问过的
if(cy[v]==-||point(cy[v]))//条件一:右边的v顶点没有左边对应的匹配的点,条件二:以v顶点在左边的匹配点为起点能够找到一条增广路(如果能够到达条件二,说明v顶点在左边一定有对应的匹配点)。
{
cx[u]=v;//更新cx,cy数组
cy[v]=u;
return ;
}
}
}
return ;//如果程序到达了这里,说明对右边所有的顶点都访问完了,没有满足条件的。
}

二分图匹配模板

中国剩余定理

LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(!b)
{
x=;y=;
return a;
}
LL res=exgcd(b,a%b,x,y);
LL t=x;
x=y;
y=t-a/b*x;
return res;
}
LL China()
{
LL m=;
LL res=;
LL x,y;
for(rint i=;i<=n;i++)m*=a[i];
for(rint i=;i<=n;i++)
{
LL tmp=m/a[i];
exgcd(tmp,a[i],x,y);
res=(res+tmp*x*b[i])%m;
}
res=(res+m)%m;
return res;
}

中国剩余定理模板

随机推荐

  1. 【leetcode】667. Beautiful Arrangement II

    题目如下: Given two integers n and k, you need to construct a list which contains ndifferent positive in ...

  2. 什么是 CSS?

    什么是 CSS? CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 HTML 4.0 中,是为了解决内容与 ...

  3. CF 1076E Vasya and a Tree(线段树+树剖)

    传送门 解题思路 首先按照每个修改时\(x\)的深度\(+d\)从大到小排序,然后按照深度分层,一层一层的修改,修改的时候就直接暴力修改子树,然后每做完一层把答案都取下来,因为以后的所有修改的深度都小 ...

  4. Transactional事务管理操作

    Transactional的属性: alue String 可选的限定描述符,指定使用的事务管理器 propagation enum: Propagation 可选的事务传播行为设置 isolatio ...

  5. 1. Python版本的选择与安装

    Python综述 Python由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年.Python是一种解释型.面向对象.动态数据类型的高级程序设计语言,它具有卓越的通 ...

  6. 词表征 3:GloVe、fastText、评价词向量、重新训练词向量

    原文地址:https://www.jianshu.com/p/ca2272addeb0 (四)GloVe GloVe本质是加权最小二乘回归模型,引入了共现概率矩阵. 1.基本思想 GloVe模型的目标 ...

  7. 前端(六)—— 伪类选择器:a标签的伪类、内容伪类、索引伪类、取反伪类

    a标签的伪类.内容伪类.索引伪类.取反伪类 一.a标签的四大伪类 :link:未访问状态 :hover:悬浮状态 :active:活跃状态 :visited:已访问状态 四大伪类也可用于其他标签 &l ...

  8. NIO 源码分析(04) 从 SelectorProvider 看 JDK SPI 机制

    目录 一.SelectorProvider SPI 二.SelectorProvider 加载过程 2.1 SelectorProvider 加载 2.2 Windows 下 DefaultSelec ...

  9. 人工智能都能写Java了!这款插件让你编程更轻松

    最近在浏览技术社区,发现了一款 IDE 插件,利用人工智能技术帮助程序员高效写代码.节省开发时间,一下子勾起了我的好奇心. 下载之后,使用一番,确实蛮好的,可以有效提升编程效率. 这款插件叫:aixc ...

  10. ps--窗口配置

    移动工具设置 v 选择图层自动选择不勾 图层ctrl + 左键 视图设置智能参考线标尺 Ctrl+r 窗口设置 关闭 库 颜色 打开 信息 字符 图层 历史记录 信息 面板选项 鼠标单位 像素 rgb ...