同余定理
(a +/- b) % c = (a % c +/- b % c) % c
(a * b) % c = (a % c) * (b % c) % c
ab % c = (a % c)b % c
快速幂取模的思想是把a^b里的b转换成2进制
把b转换成由01组成的二进制串 b = b0 * 20 + b1 * 21 + b2 * 22 + b3 * 23 + ...... + bn * 2n
那么 ab = ab0 * 20 * ab1 * 21 * ab2 * 22 * ab3 * 23 * ...... * abn * 2n
根据同余定理可得 ab % c = (ab0 * 20 % c) * (ab1 * 21 % c) * (ab2 * 22 % c) * (ab3 * 23 % c) * ...... * abn * 2n % c) % c
最后去掉bi = 0 的项(等于1) ab % c = (abi * 2i % c) * (abi+1 * 2i+1 % c) * (abi+4 * 2i+4 % c) * ...... * abn * 2n % c) % c
这里引用作者:SpiffyEight77的解释
模板:
const ll mod=1e9+7;
ll powm(ll n,ll k){
n=n%mod;
ll base=n,ans=1;
while(k){
if(k&1)
ans=(ans*base)%mod;
k=k>>1;
base=(base*base)%mod;
}
return ans%mod;
}
再记个求子序列和的笔记:
题目:
求L~R的数组子序列之和.
Input
输入数据只有1组,输入一个n,代表数组长度,然后n个整数,
然后输入m,m次询问,每次询问输入L,R.
1<=n<=1000,000;1<=m<=100,000;
1<=L<=R<=n
Output
输出数组第L个到第R个的和.
#include <bits/stdc++.h>
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)
#define ll long long int
using namespace std;
int a[1000005];
ll sum[1000005];
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
if(i==0)
sum[i]=a[i];
else
sum[i]=sum[i-1]+a[i];
}
rush(){
int b,e;
cin>>b>>e;
cout<<sum[e-1]-sum[b-2]<<endl;
}
return 0;
}