[12/11/19] 折半&倍增思想学习笔记

折半思想和倍增思想不是同一种思想,但思想接近,并且都是优化程序的黑科技。

折半

  即传说中的 Meet in the middle , 核心思想就是将原问题分成两个或多个部分,分别解决各个部分后合并。

  适用范围 这种思想一般被广泛运用于优雅的暴力,比如暴搜。当然还可以和乘法逆元之类的东西合用.

  (形如 abcdk(mod m) 的式子可化为abk(cd)1(mod m).)

  操作步骤 将一组数据分为两组,分别搜索或暴力求得答案,然后合并答案。合并时通常需要使用排序+双指针排序+二分等算法统计答案。有时并不是平均分配,可以考虑分为较小部分与较大部分,较小部分先暴搜排序,然后较大部分暴搜+二分即可剪枝。或直接分为两个较小部分与一个极小部分,极小部分直接分类讨论。

倍增

  即传说中可以直接求答案也可以用来优化 dp 的神器,核心思想就是递归计算,对于一个规模为 n 的问题,求出如适用范围的通式。

  适用范围

f(x)={g(f(x1))g(f(x2))

  其中 g(x) 为可推递推式。

  操作步骤 求递推式。若优化 dp 先思考是否可以直接倍增求得 f(x),再推 dp 方程。

//bzoj 2165
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int T,n,p;
bool flag;
ll f[70][105][105],g[105][105],t[105][105],ans,m;    //f[i][j][k] 记录从第i个房间走2^p步到达j房间最多能走几层 
                                                     //g[i][j] 记录从i房间走到j房间最多能走几层 
inline ll read()
{
    ll a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
inline void work1()
{
    for(p=1;p<=log2(m);p++)
    for(int k=1;k<=n;k++)
	for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++){
        f[p][i][j]=max(f[p-1][i][k]+f[p-1][k][j],f[p][i][j]);
        if(i==1&&f[p][i][j]>=m)return;              //已经从第一层走到了M以上 
    }
}
inline void work2()
{
    memset(t,0xef,sizeof(t));
    for(int k=1;k<=n;k++)
	for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++){
        t[i][j]=max(t[i][j],f[p][i][k]+g[k][j]);    //为了避免走第2^p步刚好跨越了M,所以只需要求出最接近M且小于M的值,再在最后ans++跨越M即可  
        if(i==1&&t[i][j]>=m)return;
    }
    memcpy(g,t,sizeof(g));                          //迭代 
    ans+=1ll<<p;
}
int main()
{
    T=read();
    while (T--) 
    {
        n=read(); m=read();
        memset(f,0xef,sizeof(f));
        memset(g,0xef,sizeof(g));
        for(int i=1;i<=n;i++)g[i][i]=0;
        ans=0;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            f[0][i][j]=read();
            if(!f[0][i][j])f[0][i][j]=-1e18;
        }
        work1();
        while(p--)work2();
        printf("%lld\n",ans+1);
    }
    return 0;
}
posted @   四氧化二磷  阅读(121)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示