zoukankan      html  css  js  c++  java
  • 模板集合

    正向表

    int tot=0,h[M];
    struct edge{
        int nxt;
        int to,cost;
    }G[3*M];
    void add(int a,int b,int c){
        G[++tot]=(edge){h[a],b,c};
        h[a]=tot;
    }
    

    LCA

    跳重链

    void dfs(int x,int f,int d){
    	dep[x]=d;
    	sz[x]=1;
    	fa[x]=f;son[x]=0; 
    	for(int i=0;i<G[x].size();i++){
    		int u=G[x][i];
    		if(u==f)continue;
    		dfs(u,x,d+1);
    		if(sz[u]>sz[son[x]])son[x]=u;
    		sz[x]+=sz[u];
    	}
    }
    void dfs_top(int x,int tp){
    	top[x]=tp;
    	if(son[x])dfs_top(son[x],tp);
    	for(int i=0;i<G[x].size();i++){
    		int u=G[x][i];
    		if(u==fa[x]||u==son[x])continue;
    		dfs_top(u,u);
    	}
    }
    int LCA(int a,int b){
    	while(top[a]!=top[b]){
    		if(dep[top[a]]>dep[top[b]])a=fa[top[a]];
    		else b=fa[top[b]];
    	}
    	return dep[a]>dep[b]?b:a;
    }
    

    倍增

    void dfs(int x,int f,int d){
    	dep[x]=d;
    	fa[x][0]=f;
    	for(int i=0;i<G[x].size();i++){
    		int u=G[x][i];
    		if(u==f)continue;
    		dfs(u,x,d+1);
    	}
    }
    int LCA(int a,int b){
    	if(dep[a]>dep[b])swap(a,b);
    	int step=dep[b]-dep[a];
    	for(int i=19;i>=0;i--)
    		if(step&1<<i)b=fa[b][i];
    	if(a==b)return a;
    	for(int i=19;i>=0;i--)
    		if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
    	return fa[a][0];
    } 
    for(int j=1;j<=19;j++)
    	for(int i=1;i<=n;i++)
    		fa[i][j]=fa[fa[i][j-1]][j-1];
    

    st表

    预处理

    void Init_RMQ(int n){
    	for(int i=1;i<=n;i++)f[i][0]=A[i];
    	lg2[1]=0;
    	for(int i=2;i<=n;i++)lg2[i]=lg2[i>>1]+1;
    	for(int j=1;(1<<j)<=n;j++)
    		for(int i=1;i+(1<<j)-1<=n;i++)
    			f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    } 
    

    查询

    int query(int l,int r){
    	int k=lg2[r-l+1];
    	return max(f[l][k],f[r-(1<<k)+1][k]);
    }
    

    数学

    扩展欧几里得算法

    void exgcd(ll a,ll b,ll &d,ll &x,ll &y){
        if(!b){d=a;x=1;y=0;return;}
        exgcd(b,a%b,d,y,x);y-=a/b*x;
    } 
    

    逆元

    int inv(int a){
        ll x,y,d;
        exgcd(a,m,d,x,y);
        return (x%MOD+MOD)%MOD;
    }
    

    线性筛逆元

    void Init(){
    	fac[0]=1;rev[1]=1;
    	for(int i=1;i<=n;i++)
    		fac[i]=(fac[i-1]*i)%MOD;
    	for(int i=2;i<=n;i++)//线性筛逆元 
    		rev[i]=(MOD-MOD/i)*rev[MOD%i]%MOD;
    }
    

    高斯消元

    void gauss(int n){
    	for(int i=1;i<=n;i++){
    		int r=i;
    		for(int j=i+1;j<=n;j++)//找到后面这一项最大的数 
    			if(fabs(a[j][i])>fabs(a[r][i]))
    				r=j;
    		for(int j=1;j<=n+1;j++) 
    			swap(a[i][j],a[r][j]);
    		for(int j=i+1;j<=n;j++){
    			double f=1.0*a[j][i]/a[i][i];
    			for(int k=i;k<=n+1;k++)
    				a[j][k]-=f*a[i][k];
    		}
    	}
    	for(int i=n;i>=1;i--){
    		for(int j=i+1;j<=n;j++)
    			a[i][n+1]-=a[j][n+1]*a[i][j];
    		a[i][n+1]/=a[i][i];
    	}
    }
    

    中国剩余定理

    for(int op=0;op<4;op++){//for需要合并的模数
        LL x,y,d;
        LL M=(mod-1)/md[op];//所有模数之和除以当前模数
        exgcd(M,md[op],d,x,y);//求出当前模数对于这个值的逆元
        x=(x%md[op]+md[op])%md[op];
        po=(po+tmp[op]*x%(mod-1)*M%(mod-1))%(mod-1);//合并上去
    }
    

    Lucas定理

    LL lucas(LL a,LL b){
        LL res=1;
        while(a&&b){
            LL x=a%mod,y=b%mod;if(y>x)return 0;
            res=res*C(x,y)%mod;
            a/=mod;b/=mod;
        }
        return res;
    }
    

    树链剖分

    寻找重儿子

    void dfs(int x,int f,int d){
    	dep[x]=d;fa[x]=f;sz[x]=1;son[x]=0;
    	for(int i=h[x];i;i=G[i].nxt){
    		int u=G[i].to;
    		if(u==f)continue;
    		dfs(u,x,d+1); 
    		if(sz[u]>sz[son[x]])son[x]=u;
    		sz[x]+=sz[u];
    	}
    }
    

    处理top

    void dfs_top(int x,int tp){
    	top[x]=tp;ID[x]=++tt;ln[tt]=x;
    	if(son[x])dfs_top(son[x],tp);
    	for(int i=h[x];i;i=G[i].nxt){
    		int u=G[i].to;
    		if(u==son[x]||u==fa[x])continue;
    		dfs_top(u,u);
    	}
    }
    

    query

    while(top[u]!=top[v]){
    	if(dep[top[u]]>dep[top[v]]){
    		query(ID[top[u]],ID[u],1);
    		u=fa[top[u]];
    	}
    	else {
    		query(ID[top[v]],ID[v],1);
    		v=fa[top[v]];
    	}
    } 
    if(dep[u]>dep[v])query(ID[v],ID[u],1);
    else query(ID[u],ID[v],1);
    

    “一起“二分

    主要是利用归并的性质。

    以3351为例:

    #include<bits/stdc++.h>
    #define M 100005
    #define LL long long
    #define P 131071
    using namespace std;
    struct erfen{
        int l,r,mid,ans,id;
        bool operator < (const erfen& res) const{
            return mid<res.mid;  
        }
    }F[M];
    int n,A[M],m;
    int X[M],Y[M],Ans[M];
    LL Val[P+5];
    void Add(int k){
        Val[X[k]]+=Y[k];
    }
    LL calc(int k){
        LL res=0;
        for(int i=k;i<=P;i=((i+1)|k)){
            res+=Val[i];
        }
        return 1LL*A[k]-res;
    }
    int main(){
    //  freopen("monster.in","r",stdin);
    //  freopen("monster.out","w",stdout);
        cin>>n;
        for(int i=0;i<n;i++)scanf("%d",&A[i]);
        cin>>m;
        for(int i=1;i<=m;i++)scanf("%d%d",&X[i],&Y[i]),X[i]&=P;
        for(int i=0;i<n;i++)F[i].l=1,F[i].r=m,F[i].ans=-1,F[i].id=i;//二分当前怪兽是在哪个点死的,如果不是则ans=-1 
        int Time=20;
        while(Time--){
            for(int i=0;i<n;i++)F[i].mid=(F[i].l+F[i].r)>>1;
            for(int i=0;i<=P;i++)Val[i]=0;
            sort(F,F+n);
            int cur=1;
            for(int i=0;i<n;i++){
                if(F[i].l>F[i].r)continue;
                while(cur<=F[i].mid&&cur<=m){Add(cur);cur++;}
                if(calc(F[i].id)<=0){
                    F[i].ans=F[i].mid;
                    F[i].r=F[i].mid-1;
                }
                else F[i].l=F[i].mid+1;
            }
        }
        for(int i=0;i<n;i++){
            if(F[i].ans==-1)continue;
            Ans[F[i].ans]--;//当前时间少了一只 
        }
        Ans[0]=n;
        for(int i=1;i<=m;i++)Ans[i]+=Ans[i-1];
        for(int i=1;i<=m;i++)printf("%d
    ",Ans[i]); 
        return 0;
    }
    
  • 相关阅读:
    清除富文本样式
    jquery--cookie应用
    Log4j 配置详解
    判断请求是否为ajax
    日期工具类
    Windows Server2012 KB2919355 补丁无法安装
    安装系统步骤:
    大白菜u盘启动盘制作工具取消赞助商方法详解
    视频使用教程
    检查网络是否正常的几种命令
  • 原文地址:https://www.cnblogs.com/zryabc/p/15412363.html
Copyright © 2011-2022 走看看