Loading

Educational Codeforces Round 85 D. Minimum Euler Cycle(模拟/数学/图)

You are given a complete directed graph KnKn with nn vertices: each pair of vertices uvu≠v in KnKn have both directed edges (u,v)(u,v) and (v,u)(v,u) ; there are no self-loops.

You should find such a cycle in KnKn that visits every directed edge exactly once (allowing for revisiting vertices).

We can write such cycle as a list of n(n1)+1n(n−1)+1 vertices v1,v2,v3,,vn(n1)1,vn(n1),vn(n1)+1=v1v1,v2,v3,…,vn(n−1)−1,vn(n−1),vn(n−1)+1=v1 — a visiting order, where each (vi,vi+1)(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][l,r] segment, in other words, vl,vl+1,,vrvl,vl+1,…,vr .

Input

The first line contains the single integer TT (1T1001≤T≤100 ) — the number of test cases.

Next TT lines contain test cases — one per line. The first and only line of each test case contains three integers nn , ll and rr (2n1052≤n≤105 , 1lrn(n1)+11≤l≤r≤n(n−1)+1 , rl+1105r−l+1≤105 ) — the number of vertices in KnKn , and segment of the cycle to print.

It's guaranteed that the total sum of nn doesn't exceed 105105 and the total sum of rl+1r−l+1 doesn't exceed 105105 .

Output

For each test case print the segment vl,vl+1,,vrvl,vl+1,…,vr of the lexicographically smallest cycle that visits every edge exactly once.

Example
Input
Copy
3
2 1 3
3 3 6
99995 9998900031 9998900031
Output
Copy
1 2 1 
1 3 2 3 
1 

整个走法应该是1 2 1 3 1 4 1 5 ...1 n 2 3 2 4 2 5..2 n ... n-1 n 1,划分一下就是[1 2 1 3 1 4 1 5] [2 3 2 4 2 5] [3 4 3 5] [4 5] [1]这样,不难发现规律。因为要满足字典序最小,所以先从1到2 3 4 5,这时如果直接回去的话必然重复,所以只能从5走到2....这样下去。
所以判断一下l和r所处情况,输出即可。注意特判最后一个区间,以及开long long
(代码垃圾,不要参考
#include <bits/stdc++.h>
using namespace std;
long long n,l,r;
long long get(long long p)
{
    long long ans=0;
    long long i;
    for(i=0;i<=n-1;i++)
    {
        if(p>i*(2*n-1-i)&&p<=(i+1)*(2*n-2-i))ans=i+1;
        if(ans)break;
    }
    if(p==n*(n-1)+1)ans=n-1;
    return ans;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%lld%lld%lld",&n,&l,&r);
        if(l==r&&l==(n-1)*n+1)
        {
            cout<<'1'<<endl;
            continue;
        }
        long long ls=get(l),rs=get(r),i,j;//ls是l所处的区间的标志 2 3 2 4 2 5 2 6标志为2 
        long long a=l-(ls-1)*(2*n-ls),//a是l在那一组的位置 
        b=(r==(n-1)*n+1)? 2*(n-rs):r-(rs-1)*(2*n-rs);//处理一下,因为r可能是最后 
        if(ls==rs)//特判 
        {
            if(l%2==0)
            {
                cout<<a/2+ls<<' ';
                for(j=a/2+ls+1;j<=b/2+rs;j++)cout<<ls<<' '<<j<<' ';
            }
            else
            {
                for(j=(a+1)/2+ls;j<=b/2+rs;j++) printf("%lld %lld ",ls,j);
            }
            if(b%2!=0)cout<<rs<<' ';
            if(r==n*(n-1)+1)cout<<1;
            cout<<endl;
            continue;
        }
        if(a%2==0)//左半截 
        {
            cout<<a/2+ls<<' ';
            for(j=a/2+ls+1;j<=n;j++) printf("%lld %lld ",ls,j);
        }
        else
        {
            for(j=(a+1)/2+ls;j<=n;j++) printf("%lld %lld ",ls,j);
        }
        for(i=ls+1;i<=rs-1;i++)//中间 
        {
            for(j=i+1;j<=n;j++)
            {
                printf("%lld %lld ",i,j);
            }
        }
        //右半截 
        {
            for(i=1;i<=b/2;i++)
            {
                printf("%lld %lld ",rs,i+rs);
            }
            if(b%2!=0)cout<<rs;
        }
        if(r==n*(n-1)+1)cout<<1;//特判 
        cout<<endl;
    }
    return 0;
 } 

 

posted @ 2020-04-12 16:32  脂环  阅读(261)  评论(0编辑  收藏  举报