分析:
给出一颗二叉树,每一条边的值为|i-j|%m,然后从给定节点出发,每次存入边值最大的节点。题解:
用优先队列保存点,BFS搜索即可AC 代码:
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <map>
#include <set>
#include <queue>
using namespace std;
typedef pair<int,int> Pii;
typedef long long LL;
typedef unsigned long long ULL;
typedef double DBL;
typedef long double LDBL;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))
int k,n,s,m;
int vis[666666];
struct node
{
int id;
int val;
bool operator< (const node &a ) const
{
if(val == a.val) return id>a.id;
return val < a.val;
}
}Node[666666];
priority_queue<node> Q;
vector<int> ans;
void solve()
{
node tmp;
tmp.id = s;
vis[s] = 1;
Q.push(tmp);
ans.clear();
while(!Q.empty())
{
tmp = Q.top();
int id = tmp.id;
ans.push_back(id);
Q.pop();
if( id/2 && !vis[id/2] )
{
vis[id/2] = 1;
tmp.id = id/2;
tmp.val = (id - id/2)%m;
Q.push(tmp);
}
if(id*2<=n && !vis[id*2])
{
vis[id*2] = 1;
tmp.id = id*2;
tmp.val = id%m;
Q.push(tmp);
}
if(id*2+1<=n && !vis[id*2+1])
{
vis[id*2+1] = 1;
tmp.id = id*2+1;
tmp.val =(id+1) % m;
Q.push(tmp);
}
}
}
int main()
{
scanf("%d", &k);
while(k--)
{
scanf("%d%d%d", &n, &s, &m);
CLR(vis);
for(int i=1;i<=n;i++)
{
Node[i].id = i;
Node[i].val = 0;
}
solve();
for(int i=0;i<n;i++)
{
if(i)
printf(" ");
printf("%d", ans[i]);
}
printf("\n");
}
return 0;
}