zoukankan      html  css  js  c++  java
  • 2020.07.24 福州大学ACM/ICPC集训队选拔赛 部分题解

    1. 对于任何一个三角形 (ABC) ,令 (f(A,B,C)) 表示其三条边的三个中点构成的点集。
      现在给定 (f(A,B,C)) 且满足所有坐标均为整数,试构造三角形 (ABC) 三个顶点坐标。
      保证答案存在且唯一。

    中位线定理可得,设三角形 (DEF) 对边的中点分别位 (ABC) ,则 (vec{BC}={1over 2}vec{FE}=vec{FA}=vec{AE})

    因此,考虑求解 (E) 点坐标等价于求解 (vec{OE}) 。则 (vec{OE}=vec{OA}+vec{AE}=vec{OA}+vec{OC}-vec{OB})

    不难知道,三角形两中点和减去第三个中点即可得到第三个中点对角的坐标。按这个方法写完排个序即可。

    【代码】

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> pii;
    pii operator + (const pii &a,const pii &b) { return pii(a.first+b.first,a.second+b.second); }
    pii operator - (const pii &a,const pii &b) { return pii(a.first-b.first,a.second-b.second); }
    int main(){
        pii Pnt[5];
        for(int i=1;i<=3;i++) cin>>Pnt[i].first>>Pnt[i].second;
        pii Ans[5];
        Ans[1]=Pnt[1]+Pnt[2]-Pnt[3];
        Ans[2]=Pnt[1]+Pnt[3]-Pnt[2];
        Ans[3]=Pnt[2]+Pnt[3]-Pnt[1];
        sort(Ans+1,Ans+4);
        for(int i=1;i<=3;i++)
            cout<<Ans[i].first<<" "<<Ans[i].second<<endl;
        return 0;
    }
    

    1. 给你两个长度为 (lenleq 10^6)​​ 的由 01 组成的二进制字符串 (n)(m) 定义 JC 的可爱值为:从 (1)(n) 中选一个数 (x),从 (1)(m) 中选一个数 (y),使得 ((x,y)) 奇偶性不同的对数.
      下面三个操作一直进行:
      累加 JC 的可爱值.
      字符串 (n) , (m) 失去他们最后一位,即 (n=lfloor{nover 2} floor,m=lfloor{mover 2} floor) ( (lfloor floor) 表示向下取整).
      如果 (n=0),或 (m=0) 退出.

    不难想出,要使得选出的 ((x,y)) 奇偶性不同,则必然是 (x)(y) 一个为奇数,一个为偶数

    由于 (n) 中的奇数个数为 (lfloor{n+1over 2} floor) ,偶数个数为 (lfloor{nover 2} floor)

    通过暴力找规律(写一个代码,算不同的 (n,m) 时,((lfloor{n+1over 2} floorcdot lfloor{mover 2} floor+lfloor{nover 2} floorcdot lfloor{m+1over 2} floor)) )亦或者稍微证明一下,不难发现,每个 (n,m) 对答案的贡献为 (lfloor{nmover 2} floor={nm-(n&1)cdot(m&1)over 2})

    现只需考虑如何实现即可:由于 (nm) 的乘积在取模意义下等于两者各自的取模,再乘积的取模。((n&1)cdot (m&1)) 仅与最后一位有关

    故将串 (n,m) 前补足 (0) ,使得两者长度相同。然后从前往后,一边记录到当前位置 (n,m) 在取模意义下的值,一边计算对答案的贡献:若当前二进制位 (n,m) 均为 (1) ,则对答案的贡献为 ((nm-1)mod p) ,否则为 (nmmod p) 。求和即可算出答案。

    【代码】

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll MOD=1e9+7,inv2=MOD+1>>1,MAXN=1e6+10;;
    stack<int> num[3];
    string s;
    inline ll ans(){
        for(int i=1;i<=2;i++){
            getline(cin,s);
            for(int j=s.size()-1;j>=0;j--)
                num[i].push(s[j]=='1');
        }
        while(num[1].size()<num[2].size()) num[1].push(0);
        while(num[1].size()>num[2].size()) num[2].push(0);
        ll A=0,B=0,Ans=0;
        for(int i=num[1].size();i>0;i--){
            int a=num[1].top(); num[1].pop();
            int b=num[2].top(); num[2].pop();
            A=((A<<1)|a)%MOD;
            B=((B<<1)|b)%MOD;
            ll Tmp=A*B-(a&b);
            Tmp=Tmp%MOD*inv2%MOD;
            Ans=(Ans+Tmp)%MOD;
        }
        return Ans;
    }
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout<<ans()<<endl;
        return 0;
    }
    

    1. 胖达发现有 (n) 只熊猫在甜筒摊前排了一个队伍,从前往后依次编号为 (1,2,cdots n)
      胖达还发现,熊猫们不喜欢老实排队。每过一会儿,会有编号为 (i) 的熊猫从队伍里走出来并插到队伍的最前面去,或者从队伍里走出来并排到队伍的末尾
      胖达很无聊,所以他时不时会问当前队伍从前往后第 (i) 个位置的熊猫的编号是多少

    这题本人做法略微有些复杂,使用了分块+双端队列

    将每 (sqrt n) 只熊猫装在一个块内,每只熊猫维护一下当前它所在的块。当熊猫 (i) 走到队首时,我们可以对于熊猫 (i) 所在的块内暴力删除这个熊猫,再把它加到开头那个分块内。接着,从它原先在的块开始,把前一个块的最后一个弹出,扔进当前块内。记得在处理时更新一下被改动的熊猫所在的块。走到队尾也是类似的处理。

    由于原先所在块内有 (sqrt n) 只熊猫,暴力删除的复杂度是 (O(sqrt n)) 的;对外每块末尾扔进后一个块,单次处理是 (O(1)) 的,总的次数是 (O(sqrt n)) 次。因此修改的复杂度是 (O(sqrt n)) 的。

    查询当前第 (i) 只熊猫,可先从分块外扫过去,直到扫到查询熊猫所在分块;在进入分块暴力查询;也可直接用公式算出在第几个分块,然后进入暴力查询。

    外面扫分块的复杂度为 (O(sqrt n)) ,用公式直接算出在哪个分块是 (O(1)) 的;分块内暴力查询的复杂度是 (O(sqrt n)) 的。因此查询的复杂度是 (O(sqrt n)) 的。

    因此,总复杂度为 (O(qsqrt n)) 。过不了就卡卡常数。

    【代码】

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=2e5+10;
    typedef deque<int> dq;
    int N,Q;
    struct SQRT{
        dq DQ;
        inline void insertBack(int val) { DQ.push_back(val); }
        inline void insertFront(int val) { DQ.push_front(val); }
        inline int popBack(){
            int res=DQ.back();
            DQ.pop_back();
            return res;
        }
        inline int popFront(){
            int res=DQ.front();
            DQ.pop_front();
            return res;
        }
        inline void popElem(int val){
            dq::iterator p=DQ.begin();
            while(*p!=val) p++;
            DQ.erase(p);
        }
        inline int ans(int pos){
            for(auto e : DQ)
                if(pos) pos--;
                else return e;
        }
    };
    struct MAIN{
        int Siz;
        int Cnt;
        int Set[MAXN];
        SQRT S[500];
        inline void Front(int val){
            int pos=Set[val],res;
            S[pos].popElem(val);
            for(int i=pos;i>0;i--){
                res=S[i-1].popBack();
                Set[res]=i;
                S[i].insertFront(res);
            }
            S[0].insertFront(val);
            Set[val]=0;
        }
        inline void Back(int val){
            int pos=Set[val],res;
            S[pos].popElem(val);
            for(int i=pos;i<Cnt;i++){
                int res=S[i+1].popFront();
                Set[res]=i;
                S[i].insertBack(res);
            }
            S[Cnt].insertBack(val);
            Set[val]=Cnt;
        }
        inline int ans(int pos){
            int Tot=0;
            for(int i=0;i<=Cnt;i++)
                if(pos>=Tot&&pos<Tot+Siz) return S[i].ans(pos-Tot)+1;
                else Tot+=Siz;
        }
    }M;
    inline void pre(){
        cin>>N>>Q;
        M.Siz=floor(sqrt(N));
        M.Cnt=(N-1)/M.Siz;
        for(int i=0;i<N;i++)
            M.S[i/M.Siz].insertBack(i),M.Set[i]=i/M.Siz;
    }
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        pre();
        int T,I;
        while(Q--&&cin>>T>>I)
            if(0);
            else if(T==1) M.Front(I-1);
            else if(T==2) M.Back(I-1);
            else if(T==3) cout<<M.ans(I-1)<<endl;
        return 0;
    }
    

    1. 有一棵 (n) 个点,编号分别为 (1)(n) 的树,其中 (s) 号点为根。
      在树上养了很多松鼠,在第 (i) 个点上住了 (A) 个雄松鼠,(B) 个雌松鼠。
      因为某些缘故,它们开始同时向根节点移动,但它们相当不安分,如果在同一个节点上,雄松鼠会和雌松鼠繁殖,简单地来说以下事件会依序发生:
      这个点的 (A) 数量变成了 (A+c imes B),这个点的 (B) 数量变成了 (B+d imes A)
      根节点的所有松鼠移动到地面,位于地面上的松鼠不会再繁殖;
      所有松鼠同时朝它们的父节点移动。
      所有事件各自都在一瞬间完成,直至树上没有松鼠。
      现在想知道最终有多少只松鼠到达了地面。

    题目有一些问题,理论上当 (A,B) 一位为 (0) 时,是不会繁殖的。但这题视为会繁殖,那就这样处理吧。

    遍历一遍整棵树,不难发现,每个节点的松鼠只会遇到同一层的松鼠。而且根据分配律可证明(先挖坑,自己还没想明白),不论同一层的松鼠怎么分配,它们最后对答案的贡献;即为它们的和,乘上层数次(根节点为 (1) 层)的矩阵 (left( egin{matrix} 1&C \ \ D&1 end{matrix} ight))

    即第 (n) 层对答案的贡献为 (left( egin{matrix} 1&C \ \ D&1 end{matrix} ight)^ncdot left( egin{matrix} displaystyle sum_{dep_i=n}A_i \ \ displaystyle sum_{dep_i=n}B_i end{matrix} ight))

    预处理出每一层对总和 (A,B) 的贡献,矩阵的乘方可以递推,累加起来即是答案。

    【代码】

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll MOD=1e9+7,MAXN=1e5+10;
    struct Matrix{
        ll Num[2][2];
    
        Matrix() { Num[0][0]=Num[0][1]=Num[1][0]=Num[1][1]=0; }
        Matrix operator * (const Matrix &x) const {
            Matrix y;
            for(int i=0;i<2;i++)
                for(int j=0;j<2;j++)
                    for(int k=0;k<2;k++)
                        y.Num[i][j]=(y.Num[i][j]+Num[i][k]*x.Num[k][j])%MOD;
            return y;
        }
        Matrix operator + (const Matrix &x) const {
            Matrix y;
            for(int i=0;i<2;i++)
                for(int j=0;j<2;j++)
                    y.Num[i][j]=(Num[i][j]+x.Num[i][j])%MOD;
            return y;
        }
    }Bas,Dep[MAXN],Mul,Ans;
    ll N,S,C,D,A[MAXN],B[MAXN];
    vector<int> Edg[MAXN];
    void dfs(int pos,int pa,int fl){
        Dep[fl].Num[0][0]+=A[pos];
        Dep[fl].Num[1][0]+=B[pos];
    
        for(auto to : Edg[pos])
            if(to!=pa)
                dfs(to,pos,fl+1);
    }
    inline void pre(){
        ios::sync_with_stdio(0);
        cin.tie(0);
        cin>>N>>S>>C>>D;
        for(int i=1;i<N;i++){
            int u,v;
            cin>>u>>v;
            Edg[u].push_back(v);
            Edg[v].push_back(u);
        }
        for(int i=1;i<=N;i++) cin>>A[i]>>B[i];
        Bas.Num[0][0]=1;
        Bas.Num[0][1]=C;
        Bas.Num[1][0]=D;
        Bas.Num[1][1]=1;
        Mul.Num[0][0]=1;
        Mul.Num[1][1]=1;
        dfs(S,0,1);
    }
    int main(){
        pre();
        for(int i=1;i<=N;i++){
            Mul=Mul*Bas;
            Ans=Ans+Mul*Dep[i];
        }
        cout<<(Ans.Num[0][0]+Ans.Num[1][0])%MOD<<endl;
        return 0;
    }
    

    1. 有一个碗状容器高度为 (H) ,容器厚度不计,用任一平行于底的水平平面截取碗得到的都是圆,且半径 (r(h)) 满足: (r(h)=r_​0+e^h,hin [0,H])
      其中 (h) 为水平截面到底部的距离,(e) 为自然对数。
      给定 (k) ,求使得容器恰好储水总容量的 (​{1over k})​​​ 时的水面高度 (h_k)

    不难列出方程 (displaystyle {1over k}int_0^Hpi r^2(h) ext dh=int_0^{h_k}pi r^2(h) ext dh)

    令变上限函数 (displaystyle f(x)=int_0^x r^2(h) ext dh) 则不难整理出 ({1over k}f(H)=f(h_k))

    由于 (f'(x)=r^2(x)geq 0)(f(x)) 单调递增,可以二分

    又因为 (displaystyle f(x)=int_0^x (r_0+e^h)^2 ext dh=({1over 2}e^{2h}+2r_0e^h+r_0^2h)|^x_0={1over 2}(e^{2x}-1)+2r_0(e^x-1)+r_0^2x) 其他的就二分可出答案

    当然,由于精度要求较低,且 ([0,H]) 枚举范围较小,可以直接 for 循环处理

    【代码】

    #include<bits/stdc++.h>
    using namespace std;
    const double esp=1e-6;
    double r0,H,K;
    inline double f(double x){
        return 0.5*(exp(2*x)-1)+(exp(x)-1)*2*r0+r0*r0*x;
    }
    int main(){
        cin>>r0>>H>>K;
        double Y=f(H)/K;
        double Head=0,Tail=H,Mid,Ans=0;
        while(Tail-Head>esp){
            Ans=Mid=(Head+Tail)/2;
            double y=f(Mid);
            if(y>Y) Tail=Mid;
            else Head=Mid;
        }
        printf("%0.2f",Ans);
        return 0;
    }
    

    1. (n) 个人(编号 ([1,n]) ),每个人说了一句话。第 (i) 个人说话内容为 (j,v) ,当 (v=1) 表示第 (i) 个人说第 (j) 个人说的是真话,若 (v=0) 表示说的是假话,若 (v=−1) 表示第 (i) 个人说不知道第 (j) 个人的话是真还是假。
      (n) 个人说的句话,每个人说的要么是真的,要么是假的,问共有多少种不同的可能?由于答案很大,请将答案对 (k) 取模

    类似于食物链。当 (v_i=1) 时,分别连接 (i,j_i)( eg i, eg j_i) ;表示若第 (i) 个人说的是真话,则第 (j_i) 个人说的是真话;若第 (i) 个人说的是假话,则第 (j_i) 个人说的是假话。

    同理,当 (v_i=0) 是,分别连接 (i, eg j_i)( eg i,j_i)(v_i=-1) 的不处理。

    则若存在 (i) 使得 (i, eg i) 处于同一并查集内,一定无解。一个人不能既说真话,又说假话。此时返回 (0)

    否则,若第 (i) 个人说了真话,则所有与它处于同一并查集的情况都应视为成立。故统计总并查集的数量 (Cnt) ,答案即为 (2^{Cntover 2}) (每个人说真话和说假话都会统计到一次)

    【代码】

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll MAXN=2e6+10;
    ll N,K;
    inline ll fpow(ll a,ll x){
        ll ans=1;
        for(;x;x>>=1,a=a*a%K) if(x&1) ans=ans*a%K;
        return ans;
    }
    ll Pa[MAXN],Vis[MAXN];
    int pa(int n) { return (n==Pa[n])?n:(Pa[n]=pa(Pa[n])); }
    inline void merge(int u,int v) { Pa[pa(u)]=pa(v); }
    inline bool isunion(int u,int v) { return pa(u)==pa(v); }
    inline void pre(){
        cin>>N>>K;
        ll J,V;
        for(int i=1;i<=N+N;i++) Pa[i]=i,Vis[i]=0;
        for(int i=1;i<=N;i++){
            cin>>J>>V;
            if(V==-1) continue;
            else if(V==1) merge(i,J),merge(i+N,J+N);
            else if(V==0) merge(i+N,J),merge(i,J+N);
        }
    }
    inline ll ans(){
        ll Cnt=0;
        for(int i=1;i<=N;i++)
            if(isunion(i,i+N)) return 0;
            else if(!Vis[pa(i)]){
                Vis[pa(i)]=1;
                Vis[pa(i+N)]=1;
                Cnt++;
            }
        return fpow(2,Cnt);
    }
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0);
        pre();
        cout<<ans()<<endl;
        return 0;
    }
    

    1. 白熊有一个长度为 (n) 的数组 (a_​1,a_​2,cdots ,a_n)
      白熊觉得这个数组的长度太短了,所以白熊想要在这个数组的末尾再添加 (m) 个数。
      白熊觉得只是添加 (m) 个数太无聊了,它希望数组在添加了 (m) 个数之后,包含的本质不同的非空子序列尽可能多。
      白熊只认识从 (1)(k)(k) 个整数,因此数组中原有的 (n) 个数与将要添加的 (m) 个数均为不超过 (k) 的正整数。
      白熊希望你告诉它,在添加了 (m) 个数后,新数组最多可以包含多少个本质不同的非空子序列,你只需要告诉它答案对 (1000000007) 取模后的结果。
      一个数组的非空子序列是指将这个数组中的某些数删去后(可以不删,但不能全部删去),剩下的数构成的序列。对于两个序列 (p,q) , 它们本质相同当且仅当 (p,q) 长度相等且对于所有下标 (i) 满足 (p_​i=q_​i)
      比如,数组 ([1,3,3]) 的非空子序列有7个: ([1], [3], [3], [1,3], [1,3], [3,3], [1,3,3]) ,本质不同的非空子序列有5个: ([1], [3], [1,3], [3,3], [1,3,3])

    考虑 (dp_n) 表示仅使用前 (n) 个数(可不全使用),构成的本质非空子序列数个数。

    先考虑 (m=0) 的情况:

    则若当前数字 (a_n) 未出现过,则 (dp_n=2dp_{n-1}+1) :之前的每个非空序列都对 (dp_n) 有贡献,大小为 (dp_{n-1}) ;后接数字 (a_n) 也对 (dp_n) 有贡献,大小为 (dp_{n-1}) ;再考虑上数字 (a_n) 自己作为一个子序列,会与之前的序列均不同,贡献为 (1)

    若当前数字 (a_n) 出现过,设之前最后一次的出现位置为 (lst_{a_n}) ,则对 (dp_n) 的贡献可理解为 (2dp_{n-1}+1) 扣去重复的部分:数字 (a_n) 自己作为子序列的,与前面的重复了,扣除 (1) ;还有需要扣除的,就是前 ((lst_{a_n}-1)) 个位置的非空子序列,后接当前数字 (a_n) 的序列重复,故再扣除 (dp[lst_{a_n}-1])

    总结一下公式:若初始化 (lst_{num}=0)

    (dp_n=egin{cases} 2dp_{n-1}+1,lst_{a_n}=0 \ \ 2dp_{n-1}-dp[lst_{a_n}-1],lst_{a_n} eq 0 end{cases})

    这里可以发现:若 (dp_{1cdots (n-1)}) 单调递增,若 (a_n) 未出现过,则 (dp_n=2dp_{n-1}+1>dp_{n-1}) ;若 (a_n) 出现过,则 (dp_n=2dp_{n-1}-dp[lst_{a_n}-1]>dp_{n-1}+dp_{n-1}-dp_{n-1}=dp_{n-1}(lst_{a_n}<n-1Rightarrow dp[lst_{a_n}-1]<dp[n-1-1]<dp[n-1]))

    又因为 (dp_0=0,dp_1=2dp_0+1=1>dp_0) ,故数学归纳法得序列 (dp_{1cdots n}) 单调递增。

    接下来我们考虑 (m eq 0) 的情况:

    由上面式子易得,若 (a_n) 未出现过,则对 (dp_n) 的贡献一定更大。故我们优先选择填涂未出现过的元素。

    ([1,k]) 均出现过,则转移方程退化为 (dp_n=2dp_{n-1}-dp[lst_{a_n}-1]) 。显然 (dp[lst_{a_n}-1]) 越小则对 (dp_n) 的贡献越大。因此我们每次需要求出最小的 (lst_{a_n}) ,之后我们填涂 (a_n) ,那么 (lst_{a_n}) 更新为当前的 (n)

    因此,我们只需要用堆维护 (lst_{a_{1cdots k}}) ,每次弹出最小值参加转移方程,之后重新插入 (n) 即可。

    【代码】

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll MOD=1e9+7,MAXN=2e5+10;
    ll N,M,K,A,Dp[MAXN<<1],Lst[MAXN];
    priority_queue<ll> pq;
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0);
        cin>>N>>M>>K;
        for(int i=1;i<=N;i++){
            cin>>A;
            if(Lst[A])
                Dp[i]=(Dp[i-1]*2-Dp[ Lst[A]-1 ])%MOD;
            else Dp[i]=(Dp[i-1]<<1|1)%MOD;
            Lst[A]=i;
        }
        for(int i=1;i<=K;i++) pq.push(-Lst[i]);
        for(int j=1,i=N+1;j<=M;j++,i++){
            if(pq.top())
                Dp[i]=(Dp[i-1]*2-Dp[ -pq.top()-1 ])%MOD;
            else Dp[i]=(Dp[i-1]<<1|1)%MOD;
            pq.pop();
            pq.push(-i);
        }
        cout<<(Dp[N+M]+MOD)%MOD<<endl;
        return 0;
    }
    

    1. 给定 (n) ,和 (n) 个非负整数构成序列 (a[1cdots n])
      对于序列 (a) ,定义集合 (S(a)) 表示序列 (a) 生成的集合,通过以下步骤任意多次:
      1.初始,(S(a)={a_i},iin [1,n])
      2.若存在 (x,yin S(a)) ,但是 (xoplus y otin S(a)) ,将其插入到 (S(a))
      定义一个集合S和非负整数x的或运算和与运算分别为:
      (S∣x={y∣x ∣ yin S}, S&x={y&x ∣ yin S})
      (q) 组询问,每组询问为以下两种类型之一:
      (1) (L) (R),令(f_​1(x)=S∣x) ,求当 (xin [L,R]) 时,本质不同的 (f_​1(x)) 的个数,即求: (∣{f_​1(x)∣xin [L,R]}∣)
      (2) (L) (R), 令(f_​2(x)=S&x) ,求当 (xin [L,R]) 时,本质不同的 (f_​2(x)) 的个数,即求: (∣{f_​2(x)∣xin [L,R]}∣)

    现证明,对于第一种询问,答案一定为 ((R-L+1))

    对于 (forall x_1 eq x_2) ,考虑是否 (f_1(x_1)=f_1(x_2))

    很显然 (x=0|xin S|x=f_1(x))

    (x_2 otin f_1(x_1)) 又因为 (x_2in f(x_2))(f(x_1) eq f(x_2))

    (x_2in f_1(x_1)) ,我们将 (x) 视为它二进制位的集合。例如 (9=1001_{(2)}) 可视为集合 ({0,3}) 。为方便描述,记为 (oldsymbol 9={0,3}) 。那么此时,必然有 (oldsymbol {x_1}subset oldsymbol{x_2}) 。否则,不妨设 (ain oldsymbol{x_1},a otin oldsymbol{x_2}) ,则对于 (forall n in f_1(x_1),exist tin S) 使得 (n=t|x_1)
    (oldsymbol{n}=oldsymbol{t}cup oldsymbol{x_1})(ain oldsymbol{n}) 恒成立。因为 (x_2in f_1(x_1)) ,故 (ain oldsymbol{x_2}) ,与假设矛盾。

    因此 (oldsymbol{x_1}subset oldsymbol{x_2}) 又因为 (x_1 eq x_2)(exist a otin oldsymbol{x_1},ain oldsymbol{x_2}) 。此时同上可得 (forall nin f_1(x_2)) 都有 (ain oldsymbol{n}) 。因此可得 (x_1 otin f_1(x_2)) 。又因为 (x_1in f_1(x_1))(f_1(x_1) eq f_1(x_2))

    综上,对于 (forall x_1 eq x_2,f(x_1) eq f(x_2)) ,故对于不同的 (xin[L,R])(f_1(x)) 并不相同。因此 (|{f_1(x)|xin [L,R]}|=|{x|xin [L,R]}|=R-L+1)

    对于 (forall x_1,x_2) ,我们考虑何时有 (f_2(x_1) eq f_2(x_2))

  • 相关阅读:
    [Java] JDBC 06 批Transaction处理 -- conn.setAutoCommit(false); // 不让其自动提交 (很重要的知识点)
    [Java] JDBC 05 TestBatch.java 批处理 Batch
    [Java] JDBC 04 TestProc.java (对存储过程进行调用 CallableStatement)
    [Java] JDBC 03 TestPrepStmt.java
    美化复选框
    美化单选框
    canvas
    html5新增标签
    旋转、水平翻转、垂直翻转
    dede让channelartlist标签支持currentstyle属性 完美解决
  • 原文地址:https://www.cnblogs.com/JustinRochester/p/13373163.html
Copyright © 2011-2022 走看看