1 条题解

  • 0
    @ 2026-4-23 22:15:11

    喵喵构造题。

    看到题目我们首先能知道:

    • 因为乘积为 22k+1(kZ)2^{2k+1}(k\in \mathbb{Z} ),所以每两个数的和都是 2k2^k
    • 由于是环形,不妨把 mm 放在第一位。

    我们不妨试着构造一点可行的例子:

    53113(5)5 \to 3 \to 1 \to 1 \to 3 (\to 5) 711(7)7 \to 1 \to 1(\to 7) 71111(7)7 \to 1 \to 1 \to 1 \to 1 (\to 7) $$21 \to 11 \to 5 \to 3 \to 1 \to 1\to 3 \to 5 \to 11 (\to 21)$$1244(12)12 \to 4 \to 4 (\to 12)

    可以发现以下性质:

    1. 序列是一个先下降,直到出现偶数(不含 00)次 11,再上升。对于下降的部分,有 ai+1=2log2aiaia_{i+1}=2^{\lceil \log_2a_i\rceil}-a_i,对于上升的部分则是下降的部分的逆序。这样操作的原因是可以尽可能快的将数字变成 11。序列长度不够可以一直往里面填 11

    2. 根据 11,我们可以知道序列长度为奇数。因为第 ii 项和 i+1i+1 项的和会等于第 ni+1n-i+1 项和第 nin-i 项的和。那么这两对对乘积的贡献的一定是 22k2^{2k}。但是例外是第 n+12\frac{n+1}{2} 项和第 n+32\frac{n+3}{2} 项,它们的值一定均为 11,而且没有按照上面的说法我们会发现这个是独一对的,贡献一定是 212^1,那么乘积一定是 22k+12^{2k+1}

    3. 根据 22,我们知道,如果把序列里面的每个数都乘上 22k2^{2k},依旧成立,但是乘上 22k+12^{2k+1} 不成立,因为会使得答案乘上 2n(2k+1)2^{n(2k+1)},而 nn 是奇数,所以 n(2k+1)n(2k+1) 也是奇数,因为原式的幂次也为奇数,相加之后变为偶数,不符合题意。所以 mm 的因子里面应该有偶数(可以为 00)个 22

    那么我们的做法就很明朗了:

    首先将 mm4m \to \frac{m}{4},直到 mmod40m\bmod 4 \ne 0

    其次,如果此时 n,mn,m 中有至少一个偶数,那么答案是 NO

    然后,我们模拟操作并记录操作次数 llm2log2mmm \to 2^{\lceil \log_2m\rceil}-m,直到 m=1m=1。序列的最小长度为 2l12l-1。注意这一步如果用 C++ 自带的 log2 或者 log2l 可能会有精度问题,可能要手写。

    最后我们判断 nn 和最小长度的大小即可。单次询问时间复杂度 O(logm)O(\log m)

    #include<bits/stdc++.h>
    
    #define int unsigned ll
    #define pii pair<int,int> 
    #define pll pair<long long,long long> 
    #define ll long long
    #define i128 __int128
    
    #define mem(a,b) memset((a),(b),sizeof(a))
    #define m0(a) memset((a),0,sizeof(a))
    #define m1(a) memset(a,-1,sizeof(a))
    #define lb(x) ((x)&-(x))
    #define lc(x) ((x)<<1)
    #define rc(x) (((x)<<1)|1)
    #define pb(G,x) (G).push_back((x))
    #define For(a,b,c) for(int a=(b);a<=(c);a++)
    #define Rep(a,b,c) for(int a=(b);a>=(c);a--)
    #define in1(a) a=read()
    #define in2(a,b) a=read(), b=read()
    #define in3(a,b,c) a=read(), b=read(), c=read()
    #define in4(a,b,c,d) a=read(), b=read(), c=read(), d=read()
    #define fst first 
    #define scd second 
    #define dbg puts("IAKIOI")
    
    using namespace std;
    
    int read() {
    	int x=0,f=1; char c=getchar();
    	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
    	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	return x*f;
    }
    void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }
    
    const int mod = 998244353;
    int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
    int inv(int a) {return qpo(a,mod-2); }
    
    const int maxn = 200050;
    
    int n,m;
    
    int lg2l(int x) {
    	For(i,1,63) if(x<=(1ull<<i)) return i-1;
    	return 63;
    }
    
    void work() {
    	in2(n,m);
    	while(m%4==0) m/=4;
    	if(n%2==0ll) return cout<<"NO\n",void();
    	if(m%2==0ll) {
    		return cout<<"NO\n",void();
    	}
    	int len=1;
    	while(m>1ll) {
    		int siz=lg2l(m)+1;
    		m=(1ull<<siz)-m;
    //		cout<<siz<<' '<<(1ull<<siz)<<' '<<m<<'\n';
    		len++;
    	}
    //	cout<<len<<'\n';
    	if(len*2-1ll>n) cout<<"NO\n";
    	else cout<<"YES\n";
    }
    
    signed main() {
    //cout<<log2(7);
    //	freopen("data.in","r",stdin);
    //	freopen("myans.out","w",stdout);
    //	ios::sync_with_stdio(false); 
    //	cin.tie(0); cout.tie(0);
    	double stt=clock();
    	int _=1;
    	_=read();
    //	cin>>_;
    	For(i,1,_) {
    		work();
    	}
    	cerr<<"\nTotal Time is:"<<(clock()-stt)*1.0/1000<<" second(s)."<<'\n';
    	return 0;
    }
    
    • 1

    信息

    ID
    9688
    时间
    1000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者