首页 > 其他分享 >Acwing127周赛第三题 构造矩阵 (套路)

Acwing127周赛第三题 构造矩阵 (套路)

时间:2023-10-29 12:11:05浏览次数:46  
标签:周赛 套路 res Acwing127 样例 long 矩阵 LL mod

题目链接:构造矩阵

题目描述

我们希望构造一个 n×m 的整数矩阵。

构造出的矩阵需满足:

每一行上的所有元素之积均等于 k。
每一列上的所有元素之积均等于 k。
保证 k 为 1 或 −1。

请你计算,一共可以构成出多少种不同的满足条件的矩阵。

由于结果可能很大,你只需要输出对 109+7 取模后的结果。

输入格式
共一行,包含三个整数 n,m,k。

输出格式
一个整数,表示对 109+7 取模后的结果。

数据范围
前 3 个测试点满足 1≤n,m≤3。
所有测试点满足 1≤n,m≤1018,k 为 1 或 −1。


难度:困难
时/空限制:1s / 256MB
总通过数:300
总尝试数:1360
来源:AcWing,第127场周赛
算法标签

样例

输入样例1:
1 1 -1
输出样例1:
1
输入样例2:
1 3 1
输出样例2:
1
输入样例3:
3 3 -1
输出样例3:
16

算法1

(两次快速幂) \(O(log(n-1*m-1))\)

套路:

把最下面一行和最右边一列拿出来,只考虑左上角这个n-1*m-1的小矩形的取法,这个小矩形每个方格可以取1或者-1,
一共2^(n-1)(m-1)种不同的取法,而对于每一行,只要确定了前m-1个,最后一个就确定了,对于每一列,只要确定了前n-1列,最后一个也确定了。
但是要注意,最右下角这个点,可能会无法确定
无标题.png

A B C 表示的是那个区域的乘积

看最后一行,由于每一行的乘积都是k,所以xA=k,所以x=k/A
看最右边一列,由于每一列的乘积都是k,所以x
B=k,所以x=k/B
那么x如果想要确定,就必须得是 k/A=k/B,也就是A要等于B
而A,B都是有左上角的矩形确定的,
AC 是m-1列的乘积,每一列成绩是k,那么AC=k^(m-1)
BC 是n-1行的乘积,每一行成绩是k,那么BC=k^(n-1)

所以,A=k^(m-1) /C, B=k^(n-1)/C
想要让A=B,对于k=1,一定成立,对于k=-1,需要m-1和n-1奇偶性相同,否则不成立

而成立的情况,答案就是左上角的小矩形的填法,也就是2^(n-1)(m-1)种不同的取法,由于指数很大,所以可以做两次快速幂,或者用欧拉函数:因为我们知道 a^(p-1) 同余1modp,a与p互质,p为质数,所以我们可以把指数mod (p-1)

C++ 代码

#include<iostream>
using namespace std;
const int  mod=10e9+7;
typedef long long LL;

LL qmi(LL a,LL k,LL p)
{
    long long res=1;
    
    while(k)
    {
        if(k&1)
        {
            res=res*a%p;
        }
        k>>=1;
        a=a*a%p;
    }
    
    return res;
}
int main()
{
    long long n,m,k;
    cin>>n>>m>>k;
    
    if(n==1||m==1)
    {
        cout<<1<<endl;
        
        return 0;
    }
     LL p = qmi(2, n - 1, mod);
     if((n + m) & 1) cout << 0;
        else cout << qmi(p, m - 1, mod);
        
    return 0;
}

算法2

(欧拉函数) \(O(log(n-1*m-1))\)

C++ 代码

#include<iostream>
using namespace std;
const int  mod=1e9+7;
typedef long long LL;

LL qmi(LL a,LL k,LL p)
{
    long long res=1;
    
    while(k)
    {
        if(k&1)
        {
            res=res*a%p;
        }
        k>>=1;
        a=a*a%p;
    }
    
    return res;
}
int main()
{
    LL n, m, k;
    cin >> n >> m >> k;

    if (k == -1 && n % 2 != m % 2) puts("0");
    else
    {
        LL t = (n - 1) % (mod - 1) * ((m - 1) % (mod - 1)) % (mod - 1);
        cout << qmi(2, t, mod) << endl;
    }

    return 0;
}

标签:周赛,套路,res,Acwing127,样例,long,矩阵,LL,mod
From: https://www.cnblogs.com/z4t15/p/17795722.html

相关文章

  • 第 116 场双周赛(双指针,背包问题,线段树+lz标记)
     本题为双指针和贪心。当我们遇到奇数个0或1时,直接将下一位改变即可。classSolution{public:intminChanges(strings){intn=s.size();intres=0;intl=0,r=-1;while(r++<n-1){if(s[l]==s[r])......
  • 第 116 场双周赛
    不知道为什么今天晚上脑子里想的全是递归  说实话四道题看了都不是很有思路也不是没有思路吧而是知道怎么做但是感觉写不出来而且莫名其妙想的全是递归的解法可能是因为浏览量最高的那篇文章也是递归22:43-23:10差不多30min写了两道题 第一题(22:58AC)100094. 子数......
  • Acwing.第126场周赛
    Acwing.第126场周赛比赛链接之前忘记整理上传了,不能有遗留问题A.蜗牛爬井蜗牛在n米深的井底往上爬,每天清晨到傍晚向上爬5米,夜间又滑下来4米,请问像这样从某天清晨开始,第几天爬到井口?输入格式一个正整数n。输出格式一个整数,表示爬到井口的天数。思路:就是一个比较简答......
  • 2023级HAUT新生周赛题解汇总
    2023级HAUT新生周赛(零)熟悉周赛规则专场:2023级HAUT新生周赛(一)@21级学长专场(张子豪,张鑫,李昊阳):2023级HAUT新生周赛(二)@曹瑞峰专场:2023级HAUT新生周赛(三)@22级学姐专场(杨焱,刘振歌,周欣滢):2023级HAUT新生周赛(四)@牛浩然专场:2023级HAUT新生周赛(五)@陈兰锴专场:......
  • 蓝桥第一场双周赛
    蓝桥第一场双周赛最后一题看了别人代码还是有点不会,有些知识还没学到,等学会了再回来补这个最后一题比赛地址三带一题目链接思路:就是一个比较简单的模拟代码:/*[[⣇⣿⠘⣿⣿⣿⡿⡿⣟⣟⢟⢟⢝⠵⡝⣿⡿⢂⣼⣿⣷⣌⠩⡫⡻⣝⠹⢿⣿⣷]],[[⡆⣿⣆⠱⣝⡵⣝⢅⠙⣿⢕⢕⢕⢕⢝⣥......
  • 第 367 场周赛(双指针,集合(upper_bound&lower_bound),前后缀分解)
    2903.找出满足差值条件的下标I2905.找出满足差值条件的下标II这两个题只有数据范围上面的差距 这个题我们大体思路是维护双指针,枚举数字,维护集合。这是灵神视频的代码classSolution:deffindIndices(self,nums:List[int],indexDifference:int,valueDiffere......
  • 第一次双周赛
    第一次双周赛7-2a*b知识点:十六进制数的高精度乘法核心代码:用两个for循环处理for(inti=0;i<len1;i++) { len3=i; for(intj=0;j<len2;j++) { z[len3]+=x[i]*y[j]; if(z[len3]>=16) { z[len3+1]+=z[len3]/16; z[len3]%=16; } len3++; } ......
  • 第五次双周赛
    第五次双周赛目录第五次双周赛L1-3帅到没朋友L1-7连续因子L2-1红色警报(并查集)L2-2秀恩爱分得快L2-3插松枝L2-4哲哲打游戏L1-3帅到没朋友看题不仔细!!坑1:00000到99999,都是五位数,不足需要补0坑2:用sum记输出数量来决定是否输出空格,不能用m!=1记,因为最后一个被......
  • 第四次双周赛
    第四次双周赛目录第四次双周赛L1-2日期格式化L1-6正整数A+B(getline)L2-1排座位(并查集)L2-2名人堂与代金券L2-3包装机(栈和队列)L2-4愿天下有情人皆是失散多年的兄妹L1-2日期格式化当时写的时候忘记补0咋写了用if硬加的printf("%02d",m);//输出m宽度为2,不足前面补0p......
  • 第三次双周赛
    第三次双周赛7-1打字疯狂枚举#include<bits/stdc++.h>usingnamespacestd;inta[15]={0};intmain(){ strings; cin>>s; intlen=s.length(); for(inti=0;i<len;i++) { switch(s[i]){ case'1': case'Q': case'A......