【知识整理】普及模板整理

专辑:知识整理

一、并查集

(1) 查找公共祖先

 int getfa(int k){
		return k==fa[k]?fa[k]:fa[k]=getfa(fa[k]);
	}

(2) 合并

    x=getfa(x),y=getfa(y);
	if (x!=y) fa[xx]=yy;

(3) 判断是否在同一个集合

    bool check(int a,int b){
      return(getfa(a)==getfa(b));
    }

二、线性筛素数

f[1]=0;
  for (int i=2;i<=MAXX;i++)
    if (f[i])
      for (int j=1;j<=maxx/i;j++)
        f[i*j]=1;

三、高精度

(1) 高精度加法

  int a[MAXX],b[MAXX];
  cin>>s1>>s2;
  for (int i=1;i<=s1.size();i++) a[i]=s1[s1.size()-i]-48;
  for (int i=1;i<=s2.size();i++) b[i]=s2[s2.size()-i]-48;
  int c[MAXX];
  memset(c,0,sizeof(c));
  int len=max(s1.size(),s2.size());
  for (int i=1;i<=len;i++){
	  c[i]+=a[i]+b[i];
	  c[i+1]=c[i]/10;
	  c[i]%=10;
  }
  int k=MAXX-1;
  while (!c[k]&&k>1) k--;
  for (int i=k;i>=1;i--) cout<<c[i];
  

(2) 高精度减法

  int a[MAXX],b[MAXX];
  cin>>s1>>s2;
  if (s1比s2小) cout<<'-',swap(s1,s2);
  for (int i=1;i<=s1.size();i++) a[i]=s1[s1.size()-i]-48;
  for (int i=1;i<=s2.size();i++) b[i]=s2[s2.size()-i]-48;
  int c[MAXX];
  memset(c,0,sizeof(c));
  int len=max(s1.size(),s2.size());
  for (int i=1;i<=len;i++){
	  c[i]+=a[i]-b[i];
	  if (c[i]<0) c[i]+=10,c[i+1]-=1;
  }
  int k=MAXX-1;
  while (!c[k]&&k>1) k--;
  for (int i=k;i>=1;i--) cout<<c[i];

(3) 高精度乘法

  int a[MAXX],b[MAXX];
  cin>>s1>>s2;
  for (int i=1;i<=s1.size();i++) a[i]=s1[s1.size()-i]-48;
  for (int i=1;i<=s2.size();i++) b[i]=s2[s2.size()-i]-48;
  int c[MAXX];
  memset(c,0,sizeof(c));
  int len1=s1.size(),len2=s2.size();
  for (int i=1;i<=len1;i++)
	for (int j=1;j<=len2;j++){
		c[i+j-1]+=a[i]*b[j];
		c[i+j]+=c[i+j-1]/10;
		c[i+j-1]%=10;
	}
  int k=MAXX-1;
  while (!c[k]&&k>1) k--;
  for (int i=k;i>=1;i--) cout<<c[i];

(4) 高精度除法

  int a[MAXX],b[MAXX];
    string s;
	long long c;
	cin>>s;
	cin>>c;
	for (int i=1;i<=s.size();i++) a[i]=s[i-1]-48;
	int len=s.size();
	int k=0;
	for (int i=1;i<=len;i++){
		k=k*10+a[i];
		b[i]=k/c;
		k%=c;
	}
	k=1;
	while (k<len&&!b[k]) k++;
	for (int i=k;i<=len;i++) cout<<b[i];
	

四、图论

(1) 建图

void insert(int xx,int yy,int zz){
    e[++len].next=linkk[xx];
    linkk[xx]=len;
    e[len].y=yy;
    e[len].v=vv;
}

(2) 遍历

voi dfs(int x){
	vis[x]=1;
	for (int i=linkk[x];i;i=e[i].next)
	  if (!vis[e[i].y]) dfs(e[i].y);
}

(3) 最短路

①dijistra
I:不用堆优化

  for (int i=1;i<=n;i++) dis[i]=a[st][i];
  memset(vis,0,sizeof(vis));
  vis[st]=1;dis[st]=0;
  for (int _=1;_<n;_++){
	  int min=MAXX,mini;
	  for (int i=1;i<=n;i++)
	    if (!vis[i]&&dis[i]<minn) minn=dis[i],mini=i;
      if (!k)break;
	  vis[k]=1;
	  for (int i=1;i<=n;i++)
	    if (!vis[i]&&dis[i]>dis[mini]+a[mini][i]) dis[i]=dis[mini]+a[mini][i];
  }

II:用堆优化

    typedef pair < int , int > pii;
    priority_queue < pii,vector<pii>,greater<pii> > q;
	memset(dis,20,sizeof(dis));
	dis[1]=0;
	q.push(make_pair(0,1));
	while (!q.empty()){
	    pii t=q.top();q.pop();
	    int x=t.second,vv=t.first;
	    if (vis[x]) continue;
	    vis[x]=1;
	    for (int i=linkk[x];i;i=e[i].next)
	      if (dis[e[i].y]>vv+e[i].v)
	        dis[e[i].y]=vv+e[i].v,q.push(make_pair(dis[e[i].y],e[i].y));
	}

②、SPFA

    memset(vis,0,sizeof(vis));
	queue < int > q;
	q.push(st);
	dis[st]=0;
	vis[st]=1;
	while (!q.empty()){
	    int x=q.front();q.pop();
		vis[x]=0;
		for (int i=linkk[x];i;i=e[i].next)
		  if (dis[e[i].y]>dis[x]+e[i].v){
		    dis[e[i].y]=dis[x]+e[i].v;
			if (!vis[e[i].y]) q.push(e[i].y),vis[e[i].y]=1;
		  }
	}

③ floyed

 for (int k=1;k<=n;k++)
      for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
          dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);

(4) 最小生成树
① Kruskal

 sort(e+1,e+len+1,mycmp(x.v<y.v));
	for (int i=1;i<=len;i++){
		int x=getfa(e[i].x),y=getfa(e[i].y);
		if (x!=y) fa[x]=y,ans+=e[i].v;
	}
	cout<<ans;

②Prim

    void Prim(){
        int now=1;
        memset(dis,20,sizeof(dis));
        for (int i=linkk[1];i;i=e[i].next) dis[e[i].y]=min(dis[e[i].y],e[i].v);
        for (int _=1;_<n;_++){
            int minn=MAXX;
            vis[now]=1;
            for (int i=1;i<=n;i++)
              if (!vis[i]&&minn>dis[i]) minn=dis[i],now=i;
            ans+=minn;
            for (int i=linkk[now];i;i=e[i].next)
              if (!vis[e[i].y]&&dis[e[i].y]>e[i].v)
                  dis[e[i].y]=e[i].v;
        }
    }

五、二分答案:

     int l=1,r=MAXX;
    	while (l+1<r){
    		int mid=(l+r)>>1;
    		if (check(mid)) l=mid;
    		else r=mid;
    	}
    	printf("%d\n",check(l)?l:r);

六、背包

(1) 0/1 背包

	for (int i=1;i<=n;i++)
	  for (int j=a[i];j<=w;j++)
	    dp[j]=max(dp[j],dp[j-a[i]]+v[i]);

(2)完全背包

	for (int i=1;i<=n;i++)
	  for (int j=w;j>=a[i];j--)
		  dp[j]=max(dp[j],dp[j-a[i]]+v[i]);

(3) 多重背包

int w[MAXX];//原来的体积
	int v[MAXX];//原来的价值
	int w_[MAXX];//二进制分解后的体积
	int v_[MAXX];//二进制分解后的价值
	int tot=0;
	for (int i=1;i<=n;i++){
		scanf("%d %d %d",&m[i],&w[i],&v[i]);
		int tmp=1;
		while (m[i]-tmp>=0){
			m[i]-=tmp;
			w_[++tot]=tmp*w[i];
			v_[tot]=tmp*v[i];
			tmp*=2;
		}
		if (m[i]>0) w_[++tot]=w[i]*m[i],v_[tot]=v[i]*m[i];
	}
	for (int i=1;i<=tot;i++)
	  for (int j=v;j>=w_[i];j--)
	    dp[j]=max(dp[j],dp[j-w_[i]]+v_[i]);

(4) 混合背包

      if (这是0/1 背包){(1)}
      else if (这是完全背包) {(2)}
      else if (这是多重背包) {(3)}

(5) 分组背包

      for (int k=1;k<=K;k++)//枚举组数
	   for (int j=w;j>=0;j--)//体积
	     for (int i=1;i<=kk[k];i++)//枚举在第k组里的物品
		    if (c>=w[i]) dp[j]=max(dp[j],dp[k-w[i]]+v[i]);

(6) 二维费用背包

for (int i=1;i<=n;i++)
   for (int j=a[i];j<=w;j++)
      for (int k=b[i];k<=w_;k++)
	dp[j][k]=min(dp[j][k],dp[j-a[i]][k-b[i]]+v[i]);

七、动态规划

(1) LIS(最长上升子序列)

         f[0]=0; 
	  for (int i=1;i<=n;i++){
	    for (int j=1;j<i;j++)
	      if (a[j]>=a[i]&&f[j]>f[i])
	        f[i]=f[j];
	      f[i]++;
	    maxx=max(maxx,f[i]);
	}

(2) LCS(最长公共子序列)

          for (int i=1;i<=n;i++)
	     for (int j=1;j<=m;j++)
		   if (a[i]==b[j]) f[i][j]=max(f[i][j],f[i-1][j-1]+1);	   
	       else f[i][j]=max(f[i][j-1],f[i-1][j]);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值