1月27日集训总结

倍增
倍增这个东西非常多玄妙,主要是通过查找2^k来优化复杂度。
今天的题模版题比较多,在理解略困难的前提下要先记住,能用在实际生活中。
1、快速幂
题目描述
给你三个整数 b,p,k,求 b^p modk。
输入格式
输入只有一行三个整数,分别代表 b,p,k
输出格式
输出一行一个字符串 b^p mod k=s,其中 b,p,k 分别为题目给定的值, s 为运算结果。
输入输出样例
输入
2 10 9
输出
2^10 mod 9=7
这道题看似和倍增没什么关系,但是这俩在思想上是有统一性的,快速幂事实上就是通过对p不断除以二以达到优化复杂度的目的,这是一个模版,记住:

#include<cstdio>
using namespace std;
long long int n,p,k;
long long int mi(long long int x,long long int y,long long int z){
	long long int res = 1;
	while(y){
		if(y % 2 == 1) res = res * x % z;
		x = x * x % z;
		y = y / 2;
	}
	return res;
}
int main()
{
	scanf("%lld %lld %lld" ,&n,&p,&k);
	printf("%lld^%lld mod %lld=%lld" ,n,p,k,mi(n,p,k) % k);
	return 0;
}

2、ST表
这是一道ST表经典题——静态区间最大值
给定一个长度为 N 的数列,和 M 次询问,求出每一次询问的区间内数字的最大值。
这道题其实没啥好说的了,就是一个理解加记忆的过程,其实就相当于你把一个大区间分成两个小的(保证小的合起来能覆盖到大的),那么小区间最大值的最大值就是大区间的最大值

#include<cstdio>
#include<algorithm>
using namespace std;
int a[1000001] = { };
int ans[1000001] = { };
int dp[100501][17] = { };
int que[100501] = { };
int m,n;
int query(int l,int r){
    int k = que[r - l + 1];
    return max(dp[l][k],dp[r - (1 << k) + 1][k]);
}
int main(){
    scanf("%d %d" ,&n,&m);
    for(int i = 1;i <= n; i++){
        scanf("%d" ,&a[i]);
    }
    for(int i = 1;i <= n; i++){
        dp[i][0] = a[i];
    }
    for(int j = 1;1 << j <= n; ++j){
        for(int i = 1;i + (1 << j) - 1 <= n; ++i){
            dp[i][j] = max(dp[i][j - 1],dp[i + (1 << (j - 1))][j - 1]);
        }
    }
    int k = 0;
    for(int i = 1;i <= n; ++i){
        if((1 << k) <= i) k++;
        que[i] = k - 1;
    }
    int h = 1;
    for(int i = 1;i <= m; i++){
        int x,y;
        scanf("%d %d" ,&x,&y);
        printf("%d\n" ,query(x,y));
    }
    return 0;
}

3、理想正方形
这道题是刚刚的升级版,就相当于是二维的ST表,按照刚刚的步骤,把二维数组改为三位的计算即可

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int a,b,n;
int ma[1010][1010][9] = { },mi[1010][1010][9] = { };
int que[1001] = { };
int ans[1010][1010] = { };
int ac[1010][1010] = { };
int max4(int a,int b,int c,int d){
    return max(a,max(b,max(c,d)));
}
int min4(int a,int b,int c,int d){
    return min(a,min(b,min(c,d)));
}
int l[1001] = { };
int p1 = 0;
int query(int x,int y){
   // int k = que[y - x + 1];
    int p,q;
    p=max4(ma[x][y][p1],ma[x + n - l[p1]][y][p1],ma[x][y + n - (1 << p1)][p1],ma[x + n - (1 << p1)][y + n - (1 << p1)][p1]);
    q=min4(mi[x][y][p1],mi[x + n - (1 << p1)][y][p1],mi[x][y + n - (1 << p1)][p1],mi[x + n - (1 << p1)][y + n - (1 << p1)][p1]);
    return p - q;
}
int main(){
    scanf("%d %d %d" ,&a,&b,&n);
    for(int i = 1;i <= a; i++){
        for(int j = 1;j <= b; j++){
            scanf("%d" ,&ac[i][j]);
        }
    }
    for(int i = 1;i <= a; i++){
        for(int j = 1;j <= b; j++){
            ma[i][j][0] = mi[i][j][0] = ac[i][j];
        }
    }
    l[0]=1;
    for(int i=1;i<=18;i++){
        l[i]=l[i-1] * 2;
    }
    
    while(l[p1 + 1] <= n){
        p1++;
    }
    for(int k = 1;k <= p1; k++){
        for(int i = 1;i + (1 << k) - 1 <= a; i++){
            for(int j = 1;j + (1 << k) - 1 <= b; j++){
                ma[i][j][k]=max4(ma[i][j][k-1],ma[i + (1 << (k - 1))][j][k-1],
                                ma[i][j + (1 << (k - 1))][k-1],ma[i + (1 << (k - 1))][j + (1 << (k - 1))][k - 1]);
                mi[i][j][k]=min4(mi[i][j][k - 1],mi[i + (1 << (k - 1))][j][k - 1],
                                mi[i][j + (1 << (k - 1))][k-1],mi[i + (1 << (k - 1))][j + (1 << (k - 1))][k - 1]);
            }
        }
    }
  //  int k = 0;
  //  for(int i = 1;i <= n; ++i){
  //      if((1 << k) <= i) k++;
  //      que[i] = k - 1;
  //  }
    int xiao = 2e9;
    for(int i = 1;i + n - 1 <= a; i++){
        for(int j = 1;j + n - 1<= b; j++){
            //if(query(i,j) < xiao) xiao = query(i,j); ///!
            xiao = min(xiao,query(i,j));
        }
    }
    printf("%d\n" ,xiao);
    return 0;
}

嗯对,这个也要努力记住,还有一道我不太会,暴搜的就得了30分,等讲过之后再整理吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值