• Educational Codeforces Round 100 (Rated for Div. 2)D. Pairs(选定取min剩余取max组成给定集合)


    题:https://codeforces.com/contest/1463/problem/D

    题意:从1~2*n之间随意取出n个pair,选定其中x个取出其中的最小值,选定其中(n-x)取出其中的最大值,组成n个数恰好是给定的set(这里记为f1数组),问0<=x<=n,有多少个取值是满足题意的(n<=2e5)。

    分析:

    • 单单考虑取最小值,看最大能取到多少个pair使得这些最小值都在set中;
    • 设f2数组为没有出现在set中的数(f1和f2数组升序),那么最大能取到的就是f1的前段和f2的后段组成pair,且具有单调性,那么可以用二分求出最大值记为maxL;
    • 取最大值同理,记为minR,那么合法的x就是在[n-minR+1,maxL]之间取(因为要保证选定pair取min的同时剩余的pair要取max最终能组成题目给的set),答案就是这个区间长度。
    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    #define MP make_pair
    #define UM unordered_map
    typedef long long ll;
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    const ll INF=1e18;
    #define pi 3.1415926535898
    #define DEC (pi/180)
    const static int M=4e5+5;
    int vis[M],f1[M<<1],f2[M<<1];
    void pn(){
        puts("NO");
    }
    void py(){
        puts("YES");
    }
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            int n;
            scanf("%d",&n);
            for(int i=1;i<=2*n;i++) vis[i]=0;
            for(int x,i=1;i<=n;i++){
                scanf("%d",&x);
                vis[x]=1;
            }
            int tot1=0,tot2=0;
            for(int i=1;i<=2*n;i++){
                if(vis[i]==1)
                    f1[++tot1]=i;
                else
                    f2[++tot2]=i;
            }
            int L=0,R=n,maxL=0;
            while(L<=R){
                int midd=(L+R)>>1;
                int ok=1;
                for(int i=1;i<=midd;i++) if(f1[i]>f2[n-midd+i]) ok=0;///要最小值为标记过的值
                if(ok){
                    L=midd+1;
                    maxL=midd;
                }
                else R=midd-1;
            }
            L=0,R=n;
            int minR=n;
            while(L<=R){
                int midd=(L+R)>>1;
                int ok=1;
                for(int i=1;i<=midd;i++) if(f2[i]>f1[n-midd+i]) ok=0;///要最大值为标记过的值
                if(ok){
                    L=midd+1;
                    minR=midd;
                }
                else R=midd-1;
            }
            printf("%d
    ",maxL-(n-minR)+1);///相交区间的长度
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【洛谷P5158】 【模板】多项式快速插值
    【洛谷P4245】 【模板】任意模数NTT
    【洛谷4781】 【模板】拉格朗日插值
    BZOJ 3625:小朋友和二叉树 多项式开根+多项式求逆+生成函数
    【洛谷】5205 【模板】多项式开根
    nowcoder73E 白兔的刁难 单位根反演+NTT
    BZOJ 3328: PYXFIB 单位根反演+矩阵乘法+二项式定理
    loj #6485. LJJ 学二项式定理 单位根反演
    Struts 2 框架搭建HelloWorld
    Struts 2 概念介绍
  • 原文地址:https://www.cnblogs.com/starve/p/14155339.html
Copyright © 2020-2023  润新知