1 条题解

  • 1
    @ 2023-6-4 19:27:22

    编号1、14、514、1919……的人,出列!

    预览版题面

    aa 个人肩并肩地排成一条直线, 你不知道他们的具体身高, 也就是说他们的身高可能是任意值

    现在, 如果有人问你, 你能否打包票至少存在一种方法使得队列中的 bb 个人向前迈出一步, 而出列的人身高是从左往右递增(或递减)的。

    题解

    结论

    n2+1n^{2}+1 个人肩并肩地排成一条直线。于是, 总能使 n+1n+1 个人向前迈出一步, 使得从左至右他们的身高是递增(或递减)的。

    下面给出该结论的证明 (鸽巢原理)

    我们首先阐明子序列的概念。如果 b1,b2,,bmb_{1}, b_{2}, \cdots, b_{m} 是一个序列, 那么, b4,b4,,b4b_{4}, b_{4}, \cdots, b_{4} 是 一个子序列, 只要 1i1<i2<<ikm1 \leqslant i_{1}<i_{2}<\cdots<i_{k} \leqslant m 。因此, b2,b4,b5,b6b_{2}, b_{4}, b_{5}, b_{6}b1,b2,,b8b_{1}, b_{2}, \cdots, b_{8} 的子序列, 伹 b2,b6,b5b_{2}, b_{6}, b_{5} 则不是。子序列 bi1,bi2,,bi2b_{i_{1}}, b_{i_{2}}, \cdots, b_{i_{2}} 若满足 $b_{i_{1}} \leqslant b_{i_{2}} \leqslant \cdots \leqslant b_{i_{2}}$ 则称为递增的(更恰当地说 是非递减的),而若满足 $b_{i_{1}} \geqslant b_{i_{2}} \geqslant \cdots \geqslant b_{i_{2}}$ 则称为递减的。 现在来证明结论。我们假设不存在长度为 n+1n+1 的递增子序列, 证朋必然存在长度 为 n+1n+1 的递减子序列。对于每一个 k=1,2,,n2+1k=1,2, \cdots, n^{2}+1 , 设 mkm_{k} 为从 aka_{k} 开始的最长的递增子序 列的长度。假设对于每一个 k=1,2,,n2+1k=1,2, \cdots, n^{2}+1 , 有 mknm_{k} \leqslant n , 使得不存在长度为 n+1n+1 的递增子 序列。因为对于每一个 k=1,2,,n2+1k=1,2, \cdots, n^{2}+1 , 都有 mk1m_{k} \geqslant 1 成立, 所以 m1,m2,,ma2+1m_{1}, m_{2}, \cdots, m_{a^{2}+1}11nn 之间的 n2+1n^{2}+1 个整数。由鸽巢原理的加强版可知, m1,m2,,mn2+1m_{1}, m_{2}, \cdots, m_{n^{2}+1} 中有 n+1n+1 个是相等 的。令

    mk1=mk2==mkn+1m_{k_{1}}=m_{k_{2}}=\cdots=m_{k_{n+1}}

    其中 $1 \leqslant k_{1}<k_{2}<\cdots<k_{n+1} \leqslant n^{2}+1$ 。假设对于某个 i=1,2,,ni=1,2, \cdots, n , 有 aki<ak1+1a_{k_{i}}<a_{k_{1+1}} 。那么, 由于 ki<ki+1k_{i}<k_{i+1} , 我们可做成一个从 aki+1a_{k_{i+1}} 开始的最长的递增子序列, 并将 akia_{k_{i}} 放在前面而得到一个从 aia_{i} , 开始的递增子序列。由于这意味着 mki>mki+1m_{k_{i}}>m_{k_{i+1}}, 因此我们得出 akiaki+1a_{k_{i}} \geqslant a_{k_{i+1}} 的结论。由于这对于每个 i=1,2,,ni=1,2, \cdots, n 均成立, 因此我们有

    $$a_{k_{1}} \geqslant a_{k_{2}} \geqslant \cdots \geqslant a_{k_{n+1}} $$

    从而得出 ak1,ak2,,akn+1a_{k_{1}}, a_{k_{2}}, \cdots, a_{k_{n+1}} 是一个长度为 n+1n+1 的递减子序列。

    标准程序 (高精部分采用__int128)

    // Idea: Codeboy
    // Data: Codeboy
    // Code: Codeboy
    // Solution: Codeboy
    
    // Problem: 编号1、14、514、1919……的人,出列!
    
    #include <bits/stdc++.h>
    using namespace std;
    typedef __int128 lll;
    template<typename T> inline void read(T &x){
        x=0;T w=1,ch=getchar();
        while(!isdigit(ch)&&ch!='-')ch=getchar();
        if(ch=='-')w=-1,ch=getchar();
        while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
        x=x*w;
    }
    
    template<typename T> inline void print(T x, bool flag = 0)
    {
    	if(!flag && x == 0){putchar('0'); return ;}
    	if (!x && flag) return ;
    	if (x < 0) putchar('-'),x = -x;
    	print(x / 10, 1);
    	putchar(x % 10 + '0');
    }
    
    bool check(lll a, lll b){
    	if((b - 1) >= LONG_LONG_MAX) return 0;
    	if((b - 1) * (b - 1) + 1 <= a) return 1;
    	return 0;
    }
    
    signed main(){
    	int T;
    	read(T);
    	while(T--){
    		lll a, b;
    		read(a); read(b);
    		if(check(a, b)) cout<<"YES"<<endl;
    		else cout<<"NO"<<endl;
    	}
    	return 0;
    }
    
    • 1

    编号1、14、514、1919……的人,出列!

    信息

    ID
    852
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    递交数
    15
    已通过
    8
    上传者