【MX-X19-T5】「FeOI Round 4.5」天使のクローバー 解题报告

分析

感觉不如 T4 难

看到这种输入很少的题目就要先考虑模拟一下。令 \(T_i\) 为转换 \(i\) 次得到的序列。

\[\begin{aligned} T_0&=01\\ T_1&=0111\\ T_2&=0111000111\\ T_3&=0111000111010111000111\\ \end{aligned} \]

对,我相信你已经观察到了 \(T_3=T_2+T_0+T_2\)(加法表示字符串拼接)。

然后由 \(T_i\) 的定义有 \(T_i=T_{i-1}+T_{i-3}+T_{i-1}\)

然后你就可以像平衡树上查找排名对应值一样的访问到 \(r\) 对应的值了。

判断是否有解只需要看变换后长度是否够长即可(你不需要真的跑 \(10^{18}\) 次,跑到长度为 \(10^{18}\) 就行了)。

代码

const int N=1e7+100;
int T,tot,a[20]={0,1,1,1,0,0,0,1,1,1};
ll len[N],x,r,k=1;
void solve(){
    scanf("%lld%lld",&x,&r);
    ++r;
    if(x<=tot && r>len[x]){printf("-1\n");return;}
    int nw=tot;
    while(nw>2){
        if(r<=len[nw-1]) --nw;
        else{
            r-=len[nw-1];
            if(r<=len[nw-3]) nw=nw-3;
            else{
                r-=len[nw-3];
                --nw;
            }
        }
    }
    --r;
    printf("%d\n",a[r]);
}
int main()
{
#if !ONLINE_JUDGE
    freopen("test.in","r",stdin);
    freopen("test.out","w",stdout);
#endif 
    len[0]=2,len[1]=4,len[2]=10,tot=2;
    while(len[tot]<=1e18){
        ++tot;
        len[tot]=len[tot-1]+len[tot-3]+len[tot-1];
        if(tot>=60) break;
    }
    T=read();
    while(T--) solve();
    return 0;
}
posted @ 2025-09-06 18:31  XiaoZi_qwq  阅读(12)  评论(0)    收藏  举报