zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:antipalindrome(数学)

    题目传送门(内部题58)


    输入格式

    第一行一个数$T$表示数据组数。
    接下来每行两个数$n$和$m$。


    输出格式

    $T$行,每行一个答案,对${10}^9+7$取模。


    样例

    样例输入:

    2
    5 6
    6 5

    样例输出:

    1920
    1620


    数据范围与提示

    对于$10\%$的数据,保证$n,mleqslant 5$。
    对于$30\%$的数据,保证$n,mleqslant 20$。
    对于$50\%$的数据,保证$n,mleqslant 500$。
    对于$70\%$的数据,保证$n,mleqslant 100,000$。
    对于$90\%$的数据,保证$n, mleqslant 1 imes  {10}^9$。
    对于$100\%$的数据,保证$n, mleqslant 1 imes {10}^{18},Tleqslant 50$。


    题解

    先来理解一下题意。

    就是说,每一位我们都可以选$1sim m$的数字,要选$n$位,没有长度大于$1$的回文串即可。

    那么就简单多了,对于第一位,这$m$个数我们都可以选;对于第二位,我们不能选和第一位一样的,所以我们可以选$m-1$个;对于以后的每一位,我们只需要保证和前两位不一样就好了,也就是$m-2$种选法,于是这道题就是让我们求$m imes (m-1) imes (m-2)^{(n-2)}$。

    要注意$n=1$时输出$m$,不然快速幂会死掉。

    时间复杂度:$Theta(log n)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=1000000007;
    long long n,m;
    long long ans;
    long long qpow(long long x,long long y)
    {
    	long long res=1;
    	while(y)
    	{
    		if(y&1)res=res*x%mod;
    		x=x*x%mod;
    		y>>=1;
    	}
    	return res;
    }
    int main()
    {
    	int T;scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%lld%lld",&n,&m);
    		m%=mod;
    		if(n==1)
    		{
    			printf("%lld
    ",m);
    			continue;
    		}
    		printf("%lld
    ",m*(m-1)%mod*qpow(m-2,n-2)%mod);
    	}
    	return 0;
    }
    

    rp++

  • 相关阅读:
    Go 语言打包静态文件
    Go 语言编写单元测试
    从开源项目看 Python 单元测试
    从开源项目看python代码注释
    Celery 源码解析八:State 和 Result
    Celery 源码解析七:Worker 之间的交互
    Celery 源码解析六:Events 的实现
    Celery 源码解析五: 远程控制管理
    Celery 源码解析四: 定时任务的实现
    覆盖equals时请遵守通用约定
  • 原文地址:https://www.cnblogs.com/wzc521/p/11593254.html
Copyright © 2011-2022 走看看