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

#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. github fork代码后提交

    点击他人github上的fork 在自己的Github上将代码拷贝下来 git clone 在本地修改代码后创建分支 git checkout -b work master(work为新建的特性分支, ...

  2. bypass_safedog

    1.SQL注入 手工bypass要点 先通过破坏关键字测试出拦截规则 之后进行针对性绕过 1.Mysql 1.1.联合注入 0x01 and绕过 直接 and 1=1 直接就会被拦截 在数值的前面加特 ...

  3. 【TCP】TCP状态

    下图所示,TCP通信过程包括三个步骤:建立TCP连接通道(三次握手).数据传输.断开TCP连接通道(四次挥手). 这里进一步探究TCP三路握手和四次挥手过程中的状态变迁以及数据传输过程.先看TCP状态 ...

  4. 【纪中集训】2019.07.11【NOIP提高组】模拟 B 组TJ

    Preface 今天的B组题确实比A组难多了... T1 Description 有一个长为\(n(n\in[1,2*10^5])\)的01串,有\(m(m\in[1,10^5])\)个限制\(a_i ...

  5. bzoj1044题解

    [题意分析] 本题等价于如下描述: 有一个长度为n的正整数序列,要求将其分解成m+1个子串,使最大子串和最小.求这个最大子串和及对应的分解方案数. [解题思路] 第一问二分+贪心即可.容易证明对于确定 ...

  6. BZOJ 2005: [Noi2010]能量采集(容斥+数论)

    传送门 解题思路 首先题目要求的其实就是\(\sum\limits_{i=1}^n \sum\limits_{j=1}^m [(gcd(i,j)-1)*2+1)]\),然后变形可得\(-n*m+2\s ...

  7. JS中的call()、apply() 以及 bind()方法用法总结

    JS中的call()方法和apply()方法用法总结  : 讲解: 调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域. function add(c,d){ return thi ...

  8. thinkphp5.1调用七牛云SDK上传文件

    thinkphp5.0 class Upload { public static function image(){ if(empty($_FILES['file']['tmp_name'])){ e ...

  9. 谈谈-Android Studio 调试功能

    先编译好要调试的程序. 1.设置断点 选定要设置断点的代码行,在行号的区域后面单击鼠标左键即可. 2.开启调试会话 点击红色箭头指向的小虫子,开始进入调试. IDE下方出现Debug视图,红色的箭头指 ...

  10. 剑指offer——43数据流中的中位数

    题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我们 ...