作者: 赵晓鹏时间限制: 1S章节: 递归与分治
#include <iostream>
#include <algorithm>
#include <queue>
#include <tuple>
#include <stack>
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
const int LENGTH=(1<<22)+3;
int A[LENGTH]={1,1};
int pos=0;
const int groupLen=25;
const int h=160;
int recordPass=0;
inline int Partition(int left, int right, int x)
{
A[pos]=A[left];
int i = left, j = right+1;
while(true)
{
while(i < j && A[--j] >= x);
while(i < j && A[++i] < x);
if(i>=j) break;
swap(A[i], A[j]);
}
A[left]=A[i];
A[i]=x;
return i;
}
int select(int first, int last, int r)
{
if(last - first < h)
{
priority_queue<int>Q(A + first, A + last + 1);
for(int i=last; i>=first; --i)
{
A[i]=Q.top();
Q.pop();
}
return A[r + first - 1];
}
pos=first+rand()%(last-first);
int x = A[pos];
int mid= Partition(first, last, x);
int res = mid - first + 1;
int locLeft=mid;
int locRight=last+1;
int m=0;
if(r < res) return select(first, mid, r);
else
{
while(true)
{
while(A[++locLeft]==x&&locLeft<locRight);
while((A[--locRight]^x)&&locLeft<locRight);
if(locLeft>=locRight)
{
m=locLeft-mid-1;
break;
}
A[locRight]=A[locLeft];
A[locLeft]=x;
}
if(m>=1&&r>=res&&r<=m+res-1) return x;
else return select(mid + 1+m, last, r - res-m);
}
}
void res(int left, int right, int leftNum, int rightNum, int k) {
int B[rightNum+1];
stack<tuple<int, int, int, int>> stk;
stk.push(make_tuple(left, right, leftNum, rightNum));
while (!stk.empty()) {
int left, right, leftNum, rightNum;
tie(left, right, leftNum, rightNum) = stk.top();
stk.pop();
if (leftNum > rightNum) {
continue;
}
int mid = (leftNum + rightNum) >> 1;
int midPos = (mid + 1) <<k;
select(left, right, midPos - left + 1);
B[mid]=A[midPos-1];
stk.push(make_tuple(midPos + 1, right, mid + 1, rightNum));
stk.push(make_tuple(left, midPos, leftNum, mid - 1));
}
for(int i=leftNum;i<=rightNum;++i){
if(i==rightNum){
printf("%d",B[i]);
}
else{
printf("%d ",B[i]);
}
}
}
int main()
{
int n,k,m;
scanf("%d%d%d", &n,&k,&m);
int len=1<<n;
for(int i=2; i<len; ++i)
{
A[i]=(A[i-1]+A[i-2])%m;
}
int unit=1<<k;
int maxNum=len/unit;
res(0, len-1, 0,maxNum-1, k);
return 0;
}