9.12——模拟赛

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(){;}
View Code

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(){;}
AC

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(){;}
AC
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
原文地址:https://www.cnblogs.com/Shy-key/p/7511535.html