Time Limit: 2000 MS Memory Limit: 262144 KB
Total Submit: 39 Accepted: 9 Page View: 153
Submit Status Discuss
Description
对于线性方程组求是一个十分有趣的而又实用的技能,一般解线性方程组的方法有五种分别为:
第一种 消元法 ,此法 最为简单,直接消掉只剩最后一个未知数,再回代求余下的未知数,但只适用于未知数个数等于方程的个数,且有解的情况.
第二种 克拉姆法则,如果行列式不等于零,则用常数向量替换系数行列式中的每一行再除以系数行列式,就是解;
第三种 逆矩阵法,同样要求系数矩阵可逆,直接建立AX=b与线性方程组的关系,X=A^-1.*b就是解
第四种 增广矩阵法,利用增广矩阵的性质(A,b)通过线性行变换,化为简约形式,确定自由变量,(各行中第一个非零元对应的未知数除外余下的就是自由变量),对自由变量进行赋值,求出其它未知数,然后写成基础解析的形式,最后写出通解.
这种方法需要先判别:增广矩阵的秩是否等于系数矩阵的秩,相等且小于未知数个数,则无穷多解;等于未知数个数,唯一解.秩不想等,无解.
第五种 计算机编程,随便用个软件,譬如Matlab,输入密令,
问:给你一个等比数列,求前 n项和,对 998424353 取模。
Input
第一行一个整数 T
(T≤105) ,表示有 T
组测试数据 。
对于每组测试数据:
输入三个整数 a,q,n,分别表示数列第一项,公比,前多少项, (|a|≤109,|q|≤109,(q≠0),n≤109) (|a|代表 a的绝对值)。
Output
对于每组测试数据,输出一个整数,表示该等比数列的前 n
项和。
3
2 2 3
3 2 500
-1 2 3
14
728273816
998424346
此题最大的坑点就是这个mod,一个不小心就发现不了这个mod不是素数,这个可以被43,137,5891整除,如果直接用公式算逆元的话会出问题的,第二组测试样列就可以验证(暴力算出来是不等的),逆元的条件是互素,不满足,因为n为1e9,所以全部暴力也是不可能的,所以我们想到了二分。
我们已n=5或4为例:
= =
= =
推广到n
= n为奇数
= n为偶数
所以得到公式:
ll RNG(int q,int n)
{
if(n==1)return 1;
if(n%2==0)return RNG(q,n/2)*(1+quick_pow(q,n/2))%mod;
else return RNG(q,n/2)*(1+quick_pow(q,n/2))%mod+quick_pow(q,n-1);
}
因为一个快速幂的的复杂度为 log(n)所以整体的的复杂度为 log^2 (n) 问题不大。
另外: 不知道这个想法偏不偏,但是想到了的话这个题也是简单题,只要发现这个mod不是素数然后想到二分来算就完事。在这题的数据方面,第一组中有一个数据的q=1的时候,用逆元来算的话会错,需要特判一下才能过第一组数据,但是第二组数据就不行啦,我专门写的一个小的数据,让暴力很快就可以跑出答案的数据发现问题,第三组数据是1e9的数据专门卡暴力的,第四组是t=1e5的,不为别的就卡你cin cout2333333。赛前预期:前期会有几个人手速及快用逆元的方法来做,然后wa好多次,后面发现问题想了一会用二分过了,后面就会有人陆陆续续的过,也有人死磕wa十几次怎么都想不到正解,也有人一上来就发现mod有问题,但是想不到正解,本以为在赛场上一共会提交50-100次,然后差不多五个人过题但是..
没想到全场没一个人过,wa了好多次,好多人都没有提交,可能是想不到正解也可能写完了不敢交。
是我太坏了,但是ICPC是残酷的你想得到就可以拿银,想不到就是铁,lwp和zq给我验题的时候都是直接想到了二分过了,所以ACM任重而道远啊。
代码:
#include
#define ll long long
#define qq printf("QAQ\n");
using namespace std;
const int maxn=1e5+5;
const int mod=998424353;
const int inf=0x3f3f3f3f;
ll quick_pow(ll a,int n)
{
ll ans=1;
while(n)
{
if(n&1)ans=ans*a%mod;
n/=2;
a=a*a%mod;
}
return ans;
}
ll RNG(int q,int n)
{
if(n==1)return 1;
if(n%2==0)return RNG(q,n/2)*(1+quick_pow(q,n/2))%mod;
else return RNG(q,n/2)*(1+quick_pow(q,n/2))%mod+quick_pow(q,n-1);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
ll a,n,q;
scanf("%lld%lld%lld",&a,&q,&n);
printf("%lld\n",(a*RNG(q,n)%mod+mod)%mod);
}
return 0;
}