• 暂时用笔记


    以下模板只是暂时记录一下下,以后会更新学习笔记

    树剖

    void dfs1(int n,int F)
    {
    	s[n]=1;//初始化子树大小为1
    	d[n]=d[F]+1;
    	f[n]=F; 
    	int V;
    	for(int i=head[n];i;i=e[i].next)
    	{
    		V=e[i].v;
    		if(V!=F)
    		{
    			dfs1(V,n);
    			s[n]+=s[V];
    			if(s[son[n]]<s[V]) son[n]=V;
    		}
    	}
    }
    void dfs2(int n,int C)
    {
    	c[n]=C;
    	if(son[n]) dfs2(son[n],C);
    	else return;
    	int V;
    	for(int i=head[n];i;i=e[i].next)
    	{
    		V=e[i].v;
    		if(V!=f[n] && V!=son[n]) dfs2(V,V);
    	}
    }
    

    树链剖分求lca

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<map>
    #include<string>
    #include<cstring>
    using namespace std;
    
    inline int read() {
        char c = getchar();
        int x = 0, f = 1;
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    const int N=500001;
    int n,m,root,cnt;
    struct node
    {
    	int u,v,next;
    }e[N<<1];
    int head[N];
    int son[N];
    int f[N],d[N],s[N],c[N];
    void add(int x,int y)
    {
    	e[++cnt].u=x;
    	e[cnt].v=y;
    	e[cnt].next=head[x];
    	head[x]=cnt;
    }
    void dfs1(int n,int F)
    {
    	s[n]=1;//初始化子树大小为1
    	d[n]=d[F]+1;
    	f[n]=F; 
    	int V;
    	for(int i=head[n];i;i=e[i].next)
    	{
    		V=e[i].v;
    		if(V!=F)
    		{
    			dfs1(V,n);
    			s[n]+=s[V];
    			if(s[son[n]]<s[V]) son[n]=V;
    		}
    	}
    }
    void dfs2(int n,int C)
    {
    	c[n]=C;
    	if(son[n]) dfs2(son[n],C);
    	else return;
    	int V;
    	for(int i=head[n];i;i=e[i].next)
    	{
    		V=e[i].v;
    		if(V!=f[n] && V!=son[n]) dfs2(V,V);
    	}
    }
    int lca(int x,int y)
    {
    	for(;c[x]!=c[y];x=f[c[x]])
    	{
    		if(d[c[x]]<d[c[y]]) swap(x,y);
    	}
    	return d[x]<d[y]? x: y;
    }
    int main() 
    {
    	cin>>n>>m>>root;
    	for(int i=1;i<n;++i)
    	{
    		int x,y;
    		cin>>x>>y;
    		add(x,y);
    		add(y,x);	
    	}
    	dfs1(root,0);
    	dfs2(root,root);
    	for(int i=1;i<=m;++i)
    	{
    		int x,y;
    		cin>>x>>y;
    		cout<<lca(x,y)<<'
    ';
    	}
    }
    

    无向图如何判断一个点c是否在某两点u,v间的最短路上?

    (dis_{u,c}+dis_{c,v}=dis_{u,v})

    三分法模板

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<map>
    #include<string>
    #include<cstring>
    using namespace std;
    #define eps 0.000000001
    inline int read() {
    	char c = getchar();
    	int x = 0, f = 1;
    	while(c < '0' || c > '9') {
    		if(c == '-') f = -1;
    		c = getchar();
    	}
    	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    	return x * f;
    }
    const int N=10l;
    int n;
    
    double l,r;
    double a[N];
    double calc(double x)
    {
    	double ans=0;
    	for(int i=n;i>=0;--i)
    	{
    		ans+=a[i]*pow(x,i);
    	}
    	return ans;
    }
    int main() 
    {
    	scanf("%d%lf%lf",&n,&l,&r);
    	for(int i=n;i>=0;i--)scanf("%lf",&a[i]);
    		while(r-l>eps){
    			double mid1=(2*l+r)/3.0,mid2=(l+2*r)/3.0;
    			if(calc(mid1)<calc(mid2))l=mid1;
    			else r=mid2;
    		}
    		printf("%.5lf",l);
    		return 0;
    	}
    

    倍增求LCA

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 500010
    using namespace std;
    int n,q,root,fa[maxn][22],dep[maxn],num,head[maxn];
    struct node{int to,pre;}e[maxn*2];
    void Insert(int from,int to){
        e[++num].to=to;
        e[num].pre=head[from];
        head[from]=num;
    }
    void dfs(int now,int father){
        fa[now][0]=father;
        dep[now]=dep[father]+1;
        for(int i=head[now];i;i=e[i].pre){
            int to=e[i].to;
            if(to==father)continue;
            dfs(to,now);
        }
    }
    int get(int a,int delta){
        for(int i=0;i<=21;i++){
            if(delta&(1<<i))a=fa[a][i];
        }return a;
    }
    int lca(int a,int b){
        if(dep[a]<dep[b])swap(a,b);
        a=get(a,dep[a]-dep[b]);
        if(a==b) return a;
        for(int i=21;i>=0;i--)
            if(fa[a][i]!=fa[b][i])
                a=fa[a][i],b=fa[b][i];
        return fa[a][0];
    }
    int main(){
        scanf("%d%d%d",&n,&q,&root);
        int x,y;
        for(int i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            Insert(x,y);Insert(y,x);
        }
        dfs(root,root);
        for(int j=1;j<=20;j++)
            for(int i=1;i<=n;i++)
                fa[i][j]=fa[fa[i][j-1]][j-1];
        while(q--){
            scanf("%d%d",&x,&y);
            printf("%d
    ",lca(x,y));
        }
    }
    

    线段树5种操作模板

    #include<cstdio>
    using namespace std;
    int n,p,a,b,m,x,y,ans;
    struct node
    {
        int l,r,value,lazy;
    }tree[400001];
    inline void build(int k,int ll,int rr)//建树 
    {
        tree[k].l=ll,tree[k].r=rr;
        if(tree[k].l==tree[k].r)
        {
            scanf("%d",&tree[k].value);
            return;
        }
        int m=(ll+rr)/2;
        build(k*2,ll,m);
        build(k*2+1,m+1,rr);
        tree[k].value=tree[k*2].value+tree[k*2+1].value;
    }
    inline void pushdown(int k)//标记下传 
    {
        tree[k*2].lazy+=tree[k].lazy;
        tree[k*2+1].lazy+=tree[k].lazy;
        tree[k*2].value+=tree[k].lazy*(tree[k*2].r-tree[k*2].l+1);
        tree[k*2+1].value+=tree[k].lazy*(tree[k*2+1].r-tree[k*2+1].l+1);
        tree[k].lazy=0;
    }
    inline void ask_point(int k)//单点查询
    {
        if(tree[k].l==tree[k].r)
        {
            ans=tree[k].value;
            return ;
        }
        if(tree[k].lazy) pushdown(k);
        int m=(tree[k].l+tree[k].r)/2;
        if(x<=m) ask_point(k*2);
        else ask_point(k*2+1);
    }
    inline void change_point(int k)//单点修改 
    {
        if(tree[k].l==tree[k].r)
        {
            tree[k].value+=y;
            return;
        }
        if(tree[k].lazy) pushdown(k);
        int m=(tree[k].l+tree[k].r)/2;
        if(x<=m) change_point(k*2);
        else change_point(k*2+1);
        tree[k].value=tree[k*2].value+tree[k*2+1].value; 
    }
    inline void ask_interval(int k)//区间查询 
    {
        if(tree[k].l>=a&&tree[k].r<=b) 
        {
            ans+=tree[k].value;
            return;
        }
        if(tree[k].lazy) pushdown(k);
        int m=(tree[k].l+tree[k].r)/2;
        if(a<=m) ask_interval(k*2);
        if(b>m) ask_interval(k*2+1);
    }
    inline void update(int k)//区间修改 
    {
        if(tree[k].l>=a&&tree[k].r<=b)
        {
            tree[k].value+=(tree[k].r-tree[k].l+1)*y;
            tree[k].lazy+=y;
            return;
        }
        if(tree[k].lazy) pushdown(k);
        int m=(tree[k].l+tree[k].r)/2;
        if(a<=m) update(k*2);
        if(b>m) update(k*2+1);
        tree[k].value=tree[k*2].value+tree[k*2+1].value;
    }
    int main()
    {
        scanf("%d",&n);//n个节点 
        build(1,1,n);//建树 
        scanf("%d",&m);//m种操作 
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&p);
            ans=0;
            if(p==1)
            {
                scanf("%d",&x);
                ask_point(1);//单点查询,输出第x个数 
                printf("%d",ans);
            } 
            else if(p==2)
            {
                scanf("%d%d",&x,&y);
                change_point(1);//单点修改 
            }
            else if(p==3)
            {
                scanf("%d%d",&a,&b);//区间查询 
                ask_interval(1);
                printf("%d
    ",ans);
            }
            else
            {
                 scanf("%d%d%d",&a,&b,&y);//区间修改 
                 update(1);
            }
        }
    }
    
  • 相关阅读:
    poj 3041 Asteroids (最大匹配最小顶点覆盖——匈牙利模板题)
    poj 2060 Taxi Cab Scheme (最小路径覆盖)
    poj 2728 Desert King (最小比例生成树)
    poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)
    poj 3463 Sightseeing( 最短路与次短路)
    研究生flag
    插入排序和堆排序
    根据二叉树的中序遍历和层次遍历还原二叉树
    关于AVL实现的代码记录
    回文数猜想(与6174问题很像)
  • 原文地址:https://www.cnblogs.com/pyyyyyy/p/11175180.html
Copyright © 2020-2023  润新知