You are given a complete directed graph Kn with n vertices: each pair of vertices u≠v in Kn have both directed edges (u,v) and (v,u); there are no self-loops.
You should find such a cycle in Kn that visits every directed edge exactly once (allowing for revisiting vertices).
We can write such cycle as a list of n(n−1)+1 vertices v1,v2,v3,…,vn(n−1)−1,vn(n−1),vn(n−1)+1=v1 — a visiting order, where each (vi,vi+1) occurs exactly once.
Find the lexicographically smallest such cycle. It’s not hard to prove that the cycle always exists.
Since the answer can be too large print its [l,r] segment, in other words, vl,vl+1,…,vr.
The first line contains the single integer T (1≤T≤100) — the number of test cases.
Next T lines contain test cases — one per line. The first and only line of each test case contains three integers n, l and r (2≤n≤105, 1≤l≤r≤n(n−1)+1, r−l+1≤105) — the number of vertices in Kn, and segment of the cycle to print.
It’s guaranteed that the total sum of n doesn’t exceed 105 and the total sum of r−l+1 doesn’t exceed 105.
For each test case print the segment vl,vl+1,…,vr of the lexicographically smallest cycle that visits every edge exactly once.
有n个点,每两个点之间都有两条单向的联通路径,求一个长度为2*n的回路,每条路径只能走一次,需要走过的点字典序最小
输出走过的点中区间为l~r的点
贪心构造一下就可以发现路径为
1 2 3 1 4 1 5...1 n 2 3 2 4 2 5...2 n 3 4 3 5... 3 n ... n-1 n 1
然后就是模拟输出
#include
#define ll long long
using namespace std;
const int maxn=3e5+5;
const int inf=0x3f3f3f3f;
ll ans[maxn];
int main()
{
int t;
ll n,l,r,num,m,mm;
scanf("%d",&t);
while(t--){
scanf("%lld %lld %lld",&n,&l,&r);
m=n-1,mm=1,num=1;
while(num+2*m<=l&&m){
num+=2*m;
--m,++mm;
}
int cnt=0;
while(num<=r&&m){
for(int i=(n-m+1);i<=n;++i){
if(num>=l&&num<=r)ans[++cnt]=mm;
++num;
if(num>=l&&num<=r)ans[++cnt]=i;
++num;
}
--m;
++mm;
}
if(num==r)ans[++cnt]=1;
for(int i=1;i<cnt;++i){
printf("%d ",ans[i]);
}
printf("%d\n",ans[cnt]);
}
return 0;
}