【傻牛的递推数列】(sequence.pas/c/cpp Time:1s Memory:256M)
【问题描述】
傻牛最近钻研各类数学递推数列。尤其是斐波那契数列。
傻牛眼中的斐波那契数列是这样的,
今天,傻牛发现,某些斐波那契项之间是成倍数关系的。例如第4项
【输入】
输入文件名sequence.in。
输入包含若干组数据,每组数据一行包括一个正整数X,意义如上。
【输出】
输出文件名sequence.out
输出包含若干行,每行对应每组数据的解。
【输入输出样例】
Sequence.in
4
Sequence.out
7
【输入输出解释】
【数据范围】
对于60%的数据,保证有X≤1000000,数据组数等于1。
对于100%的数据,保证有X≤1000000,数据组数小于等于100000。
【题解】
反正对于数学题,首先就是打暴力,再打表,然后再找规律,这个题也不例外,经打表可以发现答案就为 x 的约数和,当 x 为奇数的时候还要加上 2。
所以问题转化为求一个数的约数和即可
关于求约数和,有约数和公式:
对于已经分解的整数
有A的所有因子之和为
【代码】
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
const int size = 1000010;
typedef long long LL;
LL n,rans,prime[size],fir[size];
bool no_prime[size];
void pre_prime() {
for(LL i=2;i<=size;i++){
if(!no_prime[i]) {
prime[++prime[0]]=i;fir[i]=prime[0];
}
for(LL j=1;prime[j]*i<=size;j++){
fir[prime[j]*i]=j;
no_prime[prime[j]*i]=true;
if(i%prime[j]==0)break;
}
}
}
void work(LL x,LL ans){
if(x==1) {
rans=ans;return;
}
LL tmp=prime[fir[x]],tt=prime[fir[x]],equ=1;
while(x%tmp==0) {
equ+=tt;
tt=tt*tmp;
x/=tmp;
}
work(x,ans*equ);
}
int main() {
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
pre_prime();
while(~scanf("%lld",&n)) {
work(n,1);
if(n&1)
rans+=2;
printf("%lld\n",rans);
}
return 0;
}
【傻牛的数字游戏】(Game.pas/c/cpp Time:1s Memory:256M)
【问题描述】
傻牛最近在玩一个数字游戏。
首先,规定一个神奇的数字P,它就是1000000007。
这个游戏是这样的,首先给你一个无比巨大的数字
【输入】
输入文件名Game.in。
一行一个数字N代表操作总数。
接下N行代表顺次的N个操作,每个操作占一行,按“A X”格式给出,A=1时代表操作1,A=2时代表操作2。
【输出】
输出文件名Game.out。
输出包含N行,每行对应这个操作结束时这个数字对P的模值。
【输入输出样例】
Game.in
2
1 2
2 2
Game.out
2
1
【数据范围】
对于40%的数据,保证有A=1。
对于100%的数据,保证有
【题解】
我们可以一眼看出A=1的时候就是将答案直接乘上X即可,轻松40分。(为什么的话自行度娘)
然后其实100分的话也好拿,学了逆元的话直接秒掉,总之这题水的一B。
【代码】
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MOD = 1000000007;
typedef long long LL;
LL n,ans=1;
LL ksm(LL x,LL y,LL Mod);
LL read();
int main() {
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
n=read();
for(LL i=1,op,x;i<=n;i++) {
op=read();x=read();
if(op==1){
ans=ans*x%MOD;
printf("%lld\n",ans);
}
else{
LL ret=ksm(x,MOD-2,MOD);
ans=ans*ret%MOD;
printf("%lld\n",ans);
}
}
return 0;
}
LL ksm(LL x,LL y,LL Mod) {
x%=Mod;
LL ret=1;
while(y){
if(y&1)
ret=ret*x%Mod;
x=x*x%Mod;
y>>=1;
}
return ret;
}
LL read() {
LL ans=0;
char ch=getchar();
while(ch<'0'||ch>'9')
ch=getchar();
while(ch>='0'&&ch<='9') {
ans=ans*10+ch-'0';ch=getchar();
}
return ans;
}
【傻牛的约数研究】(divisor.pas/c/cpp Time:1s Memory:256M)
【问题描述】
傻牛最近在研究约数,它觉得这玩意很牛逼。
首先,对于一个数字X来说,设
【输入】
输入文件名为divisor.in。
一行一个整数N,意义见上。
【输出】
输出文件名为divisor.out。
一行一个整数,代表傻牛想求出的值。
【输入输出样例】
Divisor.in
4
Divisor.out
8
【样例解释】
【数据范围】
对于50%的数据,保证有N≤103。
对于100%的数据,保证有N≤106。
【题解】
这题目还可以再水一些,核心代码只有四行就可以A掉此题,不要问我为什么,因为我也不知道。。。
核心代码:
scanf("%d",&n);
for(int i=1;i<=n;i++)
ans+=n/i;
printf("%d\n",ans);
【代码】
该代码为pyh的分块代码,据说可以降到
#include <iostream>
#include <cstdio>
#define LL long long
using namespace std;
LL x,ans;
int main(){
freopen("divisor.in","r",stdin);
freopen("divisor.out","w",stdout);
scanf("%lld",&x);
for(LL i=1,it;i<=x;i=it+1){
it=x/(x/i);
ans+=(x/i)*(it-i+1);
}
printf("%lld\n",ans);
return 0;
}
总结
今天的考试是今年第一次AK,值得庆祝,不过主要是因为题目还是有点水了,下午的考试于是就GG了。。。