【题目描述】: 吃饭是自古以来令人头疼的问题,最后天天决定写一个程序来替他做决定。 现在已知有n个餐厅,编号从0到n-1。记ai表示第i天决定吃什么,令 t[i][0]=(A×a[i-1]+B×a[i-2])%n,(其实就是一个随机数) t[i][j]=(t[i][j-1]+1)%n,j≥1 天天不想去最近吃过的餐厅,所以如果在前n/2(整除)天中吃过某个餐厅,就不想再去这个餐厅。所以我们要找一个最小的k,使得t[i][k]不为前n/2(整除)天去过的餐厅。那么天天第i天就想去t[i][k]餐厅。 现在已知a1和a2,想让你输出a3…am,即接下来m-2天,天天会去哪里吃饭。 【输入描述】: 第一行两个正整数n和m。其中2≤n≤10^5,3≤m≤2×10^5; 第二行两个整数,分别为A和B。其中0≤A,B≤10^9; 第三行两个整数,为a[1]和a[2]。0≤a[1],a[2]<n,且a[1]≠a[2]; 【输出描述】: 一行m-2个整数,表示接下来m-2天里,天天去哪里吃饭。 【样例输入】: 3 4 7 11 2 0 【样例输出】: 1 2 【样例说明】: t[3][0]=(7×a[2]+11×a[1])%n=1,前面n/2=1天没有出现,所以第三天去1号餐厅。 t[4][0]=1,前面1天已经出现,所以第四天去t[4][1]=2号餐厅。 【时间限制、数据范围及描述】: 时间:1s 空间:256M 对于60% 的数据:2≤n,m≤10^4; 对于100% 的数据:2≤n≤10^5,3≤m≤2×10^5;且保证A,B为随机的两个素数,所以可以认为t[i][0]为一个随机数。 本题直接用双端队列模拟即可. Code: #include<iostream> #include<cstdio> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #include<ctime> #include<deque> using namespace std; const long long N=500005; long long n,m,A,B,a[N]; bool vis[N]; deque<long long> Q; int main(){ scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&A,&B,&a[1],&a[2]); vis[a[1]]=1; vis[a[2]]=1; Q.push_back(a[1]); Q.push_back(a[2]); for(int i=3;i<=m;i++){ long long x=(A*a[i-1]+B*a[i-2])%n; if(vis[x]){ for(int i=x;i<n;i++){ if(!vis[i]){ x=i; break; } } } if(vis[x]){ for(int i=0;i<x;i++){ if(!vis[i]){ x=i; break; } } } Q.push_back(x); vis[x]=1; a[i]=x; if(Q.size()>n/2){ vis[Q.front()]=0; Q.pop_front(); } } for(int i=3;i<=m;i++){ printf("%lld ",a[i]); } return 0; }
来源:https://www.cnblogs.com/ukcxrtjr/p/11531249.html