T1 斐波那契数列+斐波那契公约数+n<=10^18

1 #include <cstdio> 2 3 #define LL long long 4 const LL mod(1000000007); 5 6 inline void read(LL &x) 7 { 8 x=0; register char ch=getchar(); 9 for(; ch>'9'||ch<'0'; ) ch=getchar(); 10 for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0'; 11 } 12 13 LL n,m; 14 struct Matrix_fb { 15 LL e[2][2]; 16 void init_base() 17 { 18 e[0][0]=1; 19 e[0][1]=1; 20 e[1][0]=1; 21 e[1][1]=0; 22 } 23 void init_ans() 24 { 25 e[0][0]=e[0][1]=1; 26 } 27 Matrix_fb operator * (Matrix_fb x) const 28 { 29 Matrix_fb tmp; 30 for(int i=0; i<2; ++i) 31 for(int j=0; j<2; ++j) 32 { 33 tmp.e[i][j]=0; 34 for(int k=0; k<2; ++k) 35 tmp.e[i][j]+=e[i][k]*x.e[k][j],tmp.e[i][j]%=mod; 36 } 37 return tmp; 38 } 39 }ans,base; 40 41 int AC() 42 { 43 // freopen("spfa.in","r",stdin); 44 // freopen("spfa.out","w",stdout); 45 read(n); 46 if(n==1||n==2) { puts("1"); return 0; } 47 ans.init_ans(); base.init_base(); 48 for( n-=2; n; n>>=1,base=base*base) 49 if(n&1) ans=ans*base; 50 printf("%lld ",ans.e[0][0]); 51 return 0; 52 } 53 54 int Aptal=AC(); 55 int main(){;}
T2 51Nod——1431 快乐排队
题目来源: CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
收藏
关注
有一群人在排队,如果某个人想排到前面去,可以花一元钱给直接站在他前面的人,然后和这个人交换位置。如果自己没有钱了,就不能和前面的人交换。
但是呢,队列里面的人觉得排他前面的所有人一定要比较有钱的,至少不能比他自己拿的少。否则里面就会有人生气。站在队头的人一定是高兴的。
现在给出一个队列的初始状态,问能不能调整队列,使得里面的人都高兴。
样例解释:样例1中,队尾的人可以和前面的人交换,变成9 10。
Input
单组测试数据。 第一行包含一个整数n (1 ≤ n ≤ 200,000),表示队列中的人数。 第二行包含n个空格分开的整数 ai (0 ≤ ai ≤ 10^9),ai表示队列中第i个人手上拿的钱。编号从队尾开始。
Output
对于每一组数据如果能够使得所有人高兴输出Happy,否则输出Sad。
Input示例
2 11 8 2 9 8
Output示例
Happy Sad
a[i]向前或向后移动i位,a[i]+i的值是不变的、
所以我们可以处理处a[i]+=i,判断是否有重复的数

1 #include <algorithm> 2 #include <cstdio> 3 4 inline void read(int &x) 5 { 6 x=0; register char ch=getchar(); 7 for(; ch>'9'||ch<'0'; ) ch=getchar(); 8 for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0'; 9 } 10 int n,a[200005]; 11 12 int AC() 13 { 14 // freopen("small.in","r",stdin); 15 // freopen("small.out","w",stdout); 16 for(;~scanf("%d",&n); ) 17 { 18 for(int i=1; i<=n; ++i) 19 read(a[i]),a[i]+=i; 20 std::sort(a+1,a+n+1); 21 int tmp=0,pre=0; 22 for(int i=1; i<=n; ++i) 23 if(pre!=a[i]) pre=a[i],tmp++; 24 if(tmp!=n) puts("Sad"); 25 else puts("Happy"); 26 } 27 return 0; 28 } 29 30 int Aptal=AC(); 31 int main(){;}
T3 51Nod—— 1693 水群
总所周知,水群是一件很浪费时间的事,但是其实在水群这件事中,也可以找到一些有意思的东西。
比如现在,bx2k就在研究怎样水表情的问题。
首先,bx2k在对话框中输入了一个表情,接下来,他可以进行三种操作。
第一种,是全选复制,把所有表情全选然后复制到剪贴板中。
第二种,是粘贴,把剪贴板中的表情粘贴到对话框中。
第三种,是退格,把对话框中的最后一个表情删去。
假设当前对话框中的表情数是num0,剪贴板中的表情数是num1,
那么第一种操作就是num1=num0
第二种操作就是num0+=num1
第三种操作就是num0--
现在bx2k想知道,如果要得到n(1<=n<=10^6)个表情,最少需要几次操作。
请你设计一个程序帮助bx2k水群吧。
Input
一个整数n表示需要得到的表情数
Output
一个整数ans表示最少需要的操作数
Input示例
233
Output示例
17
因为多次复制连在一起是没有意义的,退格放在粘贴的前后已没有影响的、
所以 (设当前为x个表情,要进行k此操作) x-->x*k 代价为k,x-->x-k代价为k(x-->x-1,代价为1)
转为最短路模型(求x==n时的最小代价)
又因为合数次操作可以又质数次操作组合出来,所以只需要枚举质数的操作数、
dalao证的6个素数(2,3,5,7,11,13)足矣、

1 #include <cstring> 2 #include <cstdio> 3 #include <queue> 4 5 const int pri[6]={2,3,5,7,11,13}; 6 const int N(1e6+5); 7 int dis[N],n; 8 bool inq[N]; 9 10 int SPFA() 11 { 12 std::queue<int>que; 13 memset(dis,127/3,sizeof(dis)); 14 dis[1]=0; que.push(1); 15 for(int u,v; !que.empty(); ) 16 { 17 u=que.front(); que.pop(); inq[u]=0; 18 for(int i=0; i<6; ++i) 19 { 20 v=pri[i]*u; 21 if(v<n+5&&dis[v]>dis[u]+pri[i]) 22 { 23 dis[v]=dis[u]+pri[i]; 24 if(!inq[v]) inq[v]=1,que.push(v); 25 } 26 } 27 v=u-1; 28 if(v>0&&dis[v]>dis[u]+1) 29 { 30 dis[v]=dis[u]+1; 31 if(!inq[v]) inq[v]=1,que.push(v); 32 } 33 } 34 return dis[n]; 35 } 36 37 int AC() 38 { 39 scanf("%d",&n); 40 printf("%d ",SPFA()); 41 return 0; 42 } 43 44 int Aptal=AC(); 45 int main(){;}