Day6 差分和樹上差分
文章目錄
A. BZOj 4390: [Usaco2015 dec]Max Flow
題目
題解
樹上差分的模板題。
程式碼
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e4+10;
template<typename T>inline void read(T &x)
{
x=0;
T f=1,ch=getchar();
while (!isdigit(ch)) ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
int ver[maxn<<1],Next[maxn<<1],head[maxn],len;
inline void add(int x,int y)
{
ver[++len]=y,Next[len]=head[x],head[x]=len;
}
int fa[maxn],d[maxn],f[maxn][21];
inline void dfs1(int x,int father,int deep)
{
fa[x]=father,d[x]=deep;
for (int i=1;i<16;++i)
f[x][i]=f[f[x][i-1]][i-1];
for (int i=head[x];i;i=Next[i])
{
int y=ver[i];
if (y==father) continue;
f[y][0]=x;
dfs1(y,x,deep+1);
}
}
inline int lca(int x,int y)
{
if (d[x]>d[y]) swap(x,y);
for (int i=15;i>=0;--i)
if (d[f[y][i]]>=d[x])
y=f[y][i];
if (x==y) return x;
for (int i=15;i>=0;--i)
if (f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
return f[x][0];
}
int siz[maxn],sum[maxn],ans;
inline void dfs2(int x,int father)
{
siz[x]=sum[x];
for (int i=head[x];i;i=Next[i])
{
int y=ver[i];
if (y==father) continue;
dfs2(y,x);
siz[x]+=siz[y];
}
ans=max(ans,siz[x]);
}
int main()
{
int n,k;read(n);read(k);
for (int i=1;i<n;++i)
{
int x,y;
read(x);read(y);
add(x,y);add(y,x);
}
dfs1(1,0,1);
for (int i=1;i<=k;++i)
{
int a,b;
read(a);read(b);
int c=lca(a,b);
++sum[a],++sum[b],--sum[c];
if (c!=1) --sum[fa[c]];
}
dfs2(1,0);
printf("%d\n",ans);
return 0;
}
B. POJ 3417 Network
題目
題解
這道題借鑑了演算法進階的思路。
程式碼
#include<algorithm>
#include<bitset>
#include<cctype>
#include<cerrno>
#include<clocale>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<utility>
#include<vector>
#include<cwchar>
#include<cwctype>
using namespace std;
const int maxn=1e5+10;
template<typename T>inline void read(T &x)
{
x=0;
T f=1,ch=getchar();
while (!isdigit(ch)) ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
int ver[maxn<<1],Next[maxn<<1],head[maxn],len;
inline void add(int x,int y)
{
ver[++len]=y,Next[len]=head[x],head[x]=len;
}
int fa[maxn],d[maxn],f[maxn][21];
inline void dfs1(int x,int father,int deep)
{
fa[x]=father,d[x]=deep;
for (int i=1;i<=20;++i)
f[x][i]=f[f[x][i-1]][i-1];
for (int i=head[x];i;i=Next[i])
{
int y=ver[i];
if (y==father) continue;
f[y][0]=x;
dfs1(y,x,deep+1);
}
}
inline int lca(int x,int y)
{
if (d[x]>d[y]) swap(x,y);
for (int i=20;i>=0;--i)
if (d[f[y][i]]>=d[x])
y=f[y][i];
if (x==y) return x;
for (int i=20;i>=0;--i)
if (f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
return f[x][0];
}
int siz[maxn],sum[maxn],ans;
inline void dfs2(int x,int father)
{
siz[x]=sum[x];
for (int i=head[x];i;i=Next[i])
{
int y=ver[i];
if (y==father) continue;
dfs2(y,x);
siz[x]+=siz[y];
}
}
int main()
{
int n,m;
read(n);read(m);
for (int i=1;i<n;++i)
{
int x,y;
read(x);read(y);
add(x,y);add(y,x);
}
dfs1(1,0,1);
for (int i=1;i<=m;++i)
{
int a,b;
read(a);read(b);
int c=lca(a,b);
++sum[a],++sum[b],sum[c]-=2;
}
dfs2(1,0);
for (int i=1;i<=n;++i)
if (!siz[i] && i!=1) ans+=m;
else if (siz[i]==1) ++ans;
printf("%d\n",ans);
return 0;
}
C. CF 739B Alyona and a tree
題目
程式碼
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
template<typename T>inline void read(T &x)
{
x=0;
register int f=1;
register char ch=getchar();
while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar();}
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
template<typename T>inline void print(T x)
{
if (x<0) putchar('-'),x=-x;
if (x>9) print(x/10);
putchar(x%10+48);
}
int ver[maxn<<1],edge[maxn<<1],Next[maxn<<1],head[maxn],len;
inline void add(int x,int y,int z)
{
ver[++len]=y,edge[len]=z,Next[len]=head[x],head[x]=len;
}
ll d[maxn];//必須用long long,否則過不了,如果你想一直莫名WA的話,可以不管
int f[maxn][19];
int a[maxn];
int ans[maxn];
inline void dfs(int x,int fa,int dist)
{
d[x]=d[fa]+dist,f[x][0]=fa;
for (int i=1;i<=18;++i)
f[x][i]=f[f[x][i-1]][i-1];
for (int i=head[x];i;i=Next[i])
{
int y=ver[i],z=edge[i];
if (y==fa) continue;
dfs(y,x,z);
register int val=a[y],k=1,now=y;
while (k&&now)
{
if (d[now]-d[f[now][k]]<=val)
{
val-=d[now]-d[f[now][k]];
now=f[now][k];
k<<=1;
}
else k>>=1;
}
if (d[now]-d[f[now][0]]<=val)
now=f[now][0];
--ans[f[now][0]],++ans[f[y][0]];
}
ans[fa]+=ans[x];
}
int main()
{
int n,y,z;read(n);
for (int i=1;i<=n;++i)
read(a[i]);
for (int i=2;i<=n;++i)
{
read(y);read(z);
add(i,y,z);add(y,i,z);
}
dfs(1,0,0);
for (int i=1;i<=n;++i)
print(ans[i]),putchar(' ');
return 0;
}
相關文章
- 樹上字首和與差分
- [學習筆記] 樹上差分 - 圖論筆記圖論
- 字首和&差分
- 字首和 & 差分
- 差分
- 字首和與差分
- 線段樹差分及其應用
- 二維字首和&差分
- 差分2
- [NOIP2015 提高組] 運輸計劃(二分 + lca + 樹上差分)
- 二維差分
- 差分約束
- 二維字首和 & 二維差分
- 區間更新+差分
- 差分放大電路
- 2.diff差分【模板】
- 差分學習筆記筆記
- 線性差分方程解法
- 差分約束基本講解
- 二維字首和與差分、離散化技巧
- 關於區間操作查詢(字首和與差分)+樹狀陣列基礎陣列
- 差分約束學習筆記筆記
- 淺談差分約束系統
- POJ 3159-Candies(差分約束)
- 差分陣列原理與其字首和的應用陣列
- 差分約束的一些理解
- 如下屬於差分電平的是_________。
- 陣列演算法-差分陣列陣列演算法
- 差分方程自動計算專案
- 字首和與差分 圖文並茂 超詳細整理
- 【資料結構與演算法】字首和與差分資料結構演算法
- Day2 尤拉路,拓撲排序和差分約束排序
- 差分隱私(Differential Privacy)定義及其理解
- POJ3159 Candies【差分約束+最短路】
- 強化學習(六)時序差分線上控制演算法SARSA強化學習演算法
- 微商代理級差分紅制度開發模式模式
- [演算法學習筆記] 差分約束演算法筆記
- 自適應辛普森積分與誤差證明