杨丰磊
一般图带花树匹配:
#include
using namespace std;
#define N 230
int nex[N],spo[N],w[N],q[N],vis[N],mark[N];
vectorpath[N];
int n,r,u,to;
int finds(int x){ return w[x]==x?x:w[x]=finds(w[x]); }
void tog(int x,int y){
x=finds(x),y=finds(y);
if(x!=y)w[x]=y;
}
int findlca(int x,int y){
static int t=0;
t++;
while(1){
if(x){
x=finds(x);
if(vis[x]==t)return x;
vis[x]=t;
if(spo[x])x=nex[spo[x]];
else x=0;
}
swap(x,y);
}
}
void goup(int a,int p){
while(a!=p){
int b=spo[a],c=nex[b];
if(finds(c)!=p)nex[c]=b;
if(mark[b]==2)mark[q[r++]=b]=1;
if(mark[c]==2)mark[q[r++]=c]=1;
tog(a,b);tog(b,c);
a=c;
}
}
bool aug(int s){
for(int i=1;i<=n;i++)nex[i]=-1,w[i]=i,mark[i]=0,vis[i]=-1;
q[0]=s;r=1;mark[s]=1;
for(int l=0;!spo[s]&&l>n;
while(scanf("%d%d",&u,&to)!=EOF){
path[u].push_back(to);
path[to].push_back(u);
}
int ans=0;
for(int i=1;i<=n;i++)ans+=(!spo[i]&&aug(i));
printf("%d\n",ans*2);
for(int i=1;i<=n;i++){
if(spo[i])printf("%d %d\n",i,spo[i]);
spo[spo[i]]=0;
}
}
分治FFT:
#include
using namespace std;
#define N 1000005
#define go(i,a,b) for(int i=(a);i<=(b);i++)
#define ms(a,b) memset(a,b,sizeof a)
#define inf 0x3f3f3f3f
#define mid (l+r)/2
#define pi acos(-1.0)
struct Complex{
double x,y;
Complex(double _x = 0.0, double _y = 0.0){
x = _x; y = _y;
}
Complex operator -(const Complex &b)const{
return Complex(x - b.x, y - b.y);
}
Complex operator +(const Complex &b)const{
return Complex(x + b.x, y + b.y);
}
Complex operator *(const Complex &b)const{
return Complex(x * b.x - y * b.y, x * b.y + y * b.x);
}
};
void change(Complex y[],int len){
int i,j,k;
for(i = 1, j = len / 2; i < len - 1; i++){
if(i < j) swap(y[i],y[j]);
k = len / 2;
while(j >= k){
j -= k;
k /= 2;
}
if(j < k) j += k;
}
}
void fft(Complex y[],int len,int on){
change(y,len);
for(int h = 2; h <= len; h <<= 1){
Complex wn(cos(-on*2*pi/h),sin(-on*2*pi/h));
for(int j = 0; j < len; j += h){
Complex w(1,0);
for(int k = j; k < j + h / 2; k++){
Complex u = y[k];
Complex t = w * y[k + h / 2];
y[k] = u + t;
y[k + h / 2] = u - t;
w = w * wn;
}
}
}
if(on == -1){
for(int i = 0; i < len; i++) y[i].x /= len;
}
}
Complex A[N],B[N];
int f[N],a[N],n;
#define mod 313
int cdq(int l,int r){
if(l==r)return f[r];
cdq(l,mid);
int len=1;
while(len/2
长链剖分:
#include
using namespace std;
#define N 1000005
#define go(i,a,b) for(int i=(a);i<=(b);i++)
#define pb push_back
vectorpath[N];
int *f[N],son[N],len[N],ans[N],tmp[N],*id=tmp, n;
void dfs(int u,int fa){
for(int to:path[u]){
if(to==fa)continue;
dfs(to,u);
if(len[to]>len[son[u]])son[u]=to;
}
len[u]=len[son[u]]+1;
}
void dpdfs(int u,int fa){
f[u][0]=1;
if(son[u])f[son[u]]=f[u]+1,dpdfs(son[u],u),ans[u]=ans[son[u]]+1;
for(int to:path[u]){
if(to==fa||to==son[u])continue;
f[to]=id;id+=len[to];
dpdfs(to,u);
go(i,1,len[to]){
f[u][i]+=f[to][i-1];
if(f[u][i]>f[u][ans[u]]||(f[u][i]==f[u][ans[u]]&&i>n;
go(i,2,n)scanf("%d%d",&u,&to),path[u].pb(to),path[to].pb(u);
dfs(1,0);f[1]=id;id+=len[1];
dpdfs(1,0);
go(i,1,n)printf("%d\n",ans[i]);
return 0;
}
斯坦纳树:
#include
using namespace std;
#define go(i,a,b) for(int i=(a);i<=(b);i++)
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
#define inf 0x3f3f3f3f
#define N 1010
struct no{
int to,n,w;
};no eg[N*10];
int h[N],is[N],tot=1,n,m,k;
void add(int u,int to,int w){
eg[tot]={to,h[u],w};h[u]=tot++;
eg[tot]={u,h[to],w};h[to]=tot++;
}
int dp[N][1<<11],dk[1<<11];
queueq;
void spfa(int s){
go(i,1,n)if(dp[i][s]dp[x][s]+w){
dp[to][s]=dp[x][s]+w;
if(!is[to])q.push(to),is[to]=1;
}
}
}
}
int a,b[N],hx[N],u,w,to;
int main()
{
cin>>n>>m>>k;
memset(dp,inf,sizeof(dp));
memset(dk,inf,sizeof(dk));
go(i,1,m)scanf("%d%d%d",&u,&to,&w),add(u,to,w);
go(i,1,k)scanf("%d%d",&b[i],&a),dp[a][1<<(i-1)]=0,hx[b[i]]|=1<<(i-1);
sort(b+1,b+k+1);
int siz=unique(b+1,b+k+1)-b-1;
int S=(1<
#include
using namespace std;
const int mod=1000000007;
const int N=60;
const int inf=0x3f3f3f3f;
typedef pair pii;
int h[N],done[N],tot=1,n,m,k;
pii operator*(const pii &A, const pii &B) { return {A.first+B.first, 1LL*A.second*B.second%mod}; }
inline void upd(pii &A, const pii &B) {
if(A.first > B.first) A = B;
else if(A.first == B.first) A.second = (A.second+B.second)%mod;
}
pii dp[1<<12][N],dk[1<<12][N];
priority_queue,greater >Q;
vectorG[N];
void dij(pii *g, pii *f) {
for(int i = 0; i < n; i++) {
if(g[i].first != inf) Q.push({g[i].first, i});
done[i] = 0;
}
while(!Q.empty()) {
pii t = Q.top(); Q.pop();
int u = t.second;
if(done[u]) continue;
done[u] = 1;
for(int v:G[u]) if(g[v].first >= g[u].first+1) {
bool flag = g[v].first>g[u].first+1;
upd(g[v], g[u]*pii(1, 1));
upd(f[v], g[u]*pii(1, 1));
if(flag) Q.push({g[v].first, v});
}
}
}
int main()
{
while(1){
if(scanf("%d%d%d", &n, &m, &k) == -1) exit(0);
int all=(1<
按秩合并并查集:
#include
#include
#include
#include
#include
using namespace std;
const int N=200000+100;
int ans[N*2];
struct UnF
{
int size[N],fa[N],mstack[N*4],top;
void Init(int n)
{
for(int i=1; i<=n; i++)
size[i]=1;
}
int FindFather(int x)
{
if(fa[x]==0)
return x;
return FindFather(fa[x]);
}
void Link(int x,int y)
{
mstack[++top]=0;
int fa_x=FindFather(x),fa_y=FindFather(y);
if(size[fa_x]>size[fa_y])
swap(x,y),swap(fa_x,fa_y);
if(fa_x==fa_y)
return;
mstack[top]=fa_x;
fa[fa_x]=fa_y,size[fa_y]+=size[fa_x];
}
int Query(int x,int y)
{
if(FindFather(x)==FindFather(y))
return true;
return false;
}
void Undo()
{
if(mstack[top]==0)
{
top--;
return;
}
size[fa[mstack[top]]]-=size[mstack[top]];
fa[mstack[top]]=0;
top--;
}
} unf;
int n,m;
#define pii pair
struct SegmentTree
{
#define mid ((now_l+now_r)>>1)
#define lson (now<<1)
#define rson (now<<1|1)
vector w[N<<2];
void Insert(int l,int r,int x,int y,int now,int now_l,int now_r)
{
if(now_l>=l and now_r<=r)
{
w[now].push_back(pii(x,y));
return;
}
if(l<=mid)
Insert(l,r,x,y,lson,now_l,mid);
if(r>mid)
Insert(l,r,x,y,rson,mid+1,now_r);
}
void dfs(int now,int now_l,int now_r)
{
if(now_l>now_r)
return;
for(pii x:w[now])
unf.Link(x.first,x.second);
if(now_l==now_r)
ans[now_l]=unf.Query(1,n);
else
{
dfs(lson,now_l,mid);
dfs(rson,mid+1,now_r);
}
for(int i=0; i>n>>m;
unf.Init(n+1);
go(i,1,m)
{
scanf("%d%d%d%d",&d[i].u,&d[i].to,&d[i].l,&d[i].r);
lsx[i]=d[i].l,lsx[m+i]=d[i].r+1;
}
sort(lsx+1,lsx+m*2+1);
int q=unique(lsx+1,lsx+m*2+1)-(lsx+1);
go(i,1,m)
{
int l=lower_bound(lsx+1,lsx+q+1,d[i].l)-lsx;
int r=lower_bound(lsx+1,lsx+q+1,d[i].r+1)-lsx-1;
sgt.Insert(l,r,d[i].u,d[i].to,1,1,q);
}
sgt.dfs(1,1,q);
int as=0;
go(i,1,q)if(ans[i])
as+=lsx[i+1]-lsx[i];
cout<
LCT:
#include
using namespace std;
#define N 200005
#define ls c[x][0]
#define rs c[x][1]
struct LCT
{
int fa[N],ch[N][2],rev[N],sz[N],q[N];
void init()
{
memset(ch,0,sizeof ch);
memset(fa,0,sizeof fa);
memset(sz,0,sizeof sz);
memset(rev,0,sizeof rev);
}
inline bool isroot(int x)
{
return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
}
inline void pushup(int x)
{
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
}
inline void pushdown(int x)
{
if(rev[x])
{
rev[x]=0;
swap(ch[x][0],ch[x][1]);
rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
}
}
inline void Rotate(int x)
{
int y=fa[x],z=fa[y],l,r;
if(ch[y][0]==x)
l=0,r=l^1;
else
l=1,r=l^1;
if(!isroot(y))
{
if(ch[z][0]==y)
ch[z][0]=x;
else
ch[z][1]=x;
}
fa[x]=z;
fa[y]=x;
fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];
ch[x][r]=y;
pushup(y);
pushup(x);
}
inline void splay(int x)
{
int top=1;
q[top]=x;
for(int i=x; !isroot(i); i=fa[i])
q[++top]=fa[i];
for(int i=top; i; i--)
pushdown(q[i]);
while(!isroot(x))
{
int y=fa[x],z=fa[y];
if(!isroot(y))
{
if((ch[y][0]==x)^(ch[z][0]==y))
Rotate(x);
else
Rotate(y);
}
Rotate(x);
}
}
inline void access(int x)
{
for(int y=0; x; y=x,x=fa[x])
splay(x),ch[x][1]=y,pushup(x);
}
inline void makeroot(int x)
{
access(x),splay(x),rev[x]^=1;
}
inline int findroot(int x)
{
access(x),splay(x);
while(ch[x][0])
x=ch[x][0];
return x;
}
inline void split(int x,int y)
{
makeroot(x),access(y),splay(y);
}
inline void cut(int x,int y)
{
split(x,y);
if(ch[y][0]==x)
ch[y][0]=0,fa[x]=0;
}
inline void link(int x,int y)
{
makeroot(x),fa[x]=y,splay(x);
}
} lct;
int fa[N][22],h[N];
int n,m,l,rr,op,tot;
inline int getfa(int u,int k)
{
for(int i=16; i>=0; i--)
if((1<>T;
while(T--)
{
scanf("%d",&n);
lct.init();
for(int i=2; i<=n; i++)
scanf("%d",&fa[i][0]);
for(int j=1; j<=17; j++)
for(int i=1; i<=n; i++)
fa[i][j]=fa[fa[i][j-1]][j-1];
for(int i=1; i<=n; i++)
scanf("%d",&v[i]);
for(int i=1; i<=n; i++)
lct.link(i,getfa(i,v[i]));
scanf("%d",&m);
for(int i=1; i<=m; i++)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d",&rr);
lct.split(n+1,rr);
printf("%d\n",lct.sz[rr]-1);
}
else
{
scanf("%d %d",&l,&rr);
lct.cut(l,getfa(l,v[l]));
v[l]=rr;
lct.link(l,getfa(l,v[l]));
}
}
//for(int i=1;i<=n;i++)cut(i,getfa(i,v[i]));
}
return 0;
}
欧拉回路路径树
#include
using namespace std;
#define N 300005
#define go(i,a,b) for(int i=(a);i<=(b);i++)
#define inf 0x3f3f3f3f
#define mod 998244353
#define ll long long
int ny(int x){return x==1?1:1ll*ny(mod%x)*(mod-mod/x)%mod; }
ll a[410][410],jx[N];
int in[N],out[N],n;
ll det(int n)//求前n行n列的行列式的值
{
go(i,1,n)go(j,1,n)a[i][j]=(a[i][j]%mod+mod)%mod;
ll ret=1;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
while(a[j][i])
{
ll t=a[i][i]/a[j][i];
for(int k=i;k<=n;++k)
a[i][k]=((a[i][k]-a[j][k]*t)%mod+mod)%mod;
for(int k=i;k<=n;++k)
swap(a[i][k],a[j][k]);
ret=-ret;
}
if(!a[i][i])
return 0;
ret=ret*a[i][i]%mod;
}
ret=(ret%mod+mod)%mod;
return ret;
}
int x,cas=1;
int main()
{
jx[0]=1;go(i,1,N-1)jx[i]=jx[i-1]*i%mod;
while(scanf("%d",&n)!=EOF){
ll ans=1;
go(i,0,n)go(j,0,n)a[i][j]=out[i]=in[i]=0;
go(i,1,n){
go(j,1,n){
scanf("%d",&x);
a[i][j]-=x;
a[j][j]+=x;
in[i]+=x;
out[j]+=x;
if(x)(ans*=ny(jx[x]))%=mod;
}
(ans*=(jx[in[i]-1]+mod)%mod)%=mod;
}
int fl=1;
go(i,1,n)if(in[i]!=out[i])fl=0;
(ans*=det(n-1))%=mod;
// cout<
李超树
#include
#include
using namespace std;
#define N 200005
#define ll long long
#define mod 1000000007
#define go(i,a,b) for(int i=(a);i<=(b);i++)
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define inf 0x3f3f3f3f
#define ld long double
#define pii pair
#define vi vector
#define add(a,b) (a+=(b)%mod)%=mod
#define lowb(x,c,len) lower_bound(c+1,c+len+1,x)-c
#define uppb(x,c,len) upper_bound(c+1,c+len+1,x)-c
#define ls i*2+1
#define rs i*2+2
#define mid (l+r)/2
#define lson l,mid,ls
#define rson mid+1,r,rs
#define root 1,n,0
#define ms(a,b) memset(a,b,sizeof a)
#define muti int T;cin>>T;while(T--)
int t[N*4];
ld k[N],b[N];
ld lsx[N],x[N],y[N];
ld f(int id,int x){return k[id]*lsx[x]+b[id]; }
void updata(int x,int l,int r,int i){
if(f(x,l)>=f(t[i],l)&&f(x,r)>=f(t[i],r))return ;
if(f(x,l)>w>>n>>c;
k[0]=1,b[0]=0;
go(i,1,n)cin>>lsx[i]>>x[i]>>y[i];
go(i,1,n){
sum=query(i,root);
k[i]=y[i]/x[i];b[i]=sum-k[i]*lsx[i]+c;
updata(i,root);
if(sum+c
posted on
2019-09-18 17:06 自由缚 阅读(
...) 评论(
...) 编辑 收藏