zoukankan      html  css  js  c++  java
  • 10-19 AHS of FCGRC 模拟赛

    A.

    原题显然可以化为选择若干个数使得它们在“1“位上没有重复(^的本质是不进位加法,只要不进位就没有损失)。

    考虑对于每个端点l,找到最远的端点r使得这个[l,r]区间满足题意,那么这里有r-l+1种满足题意的方案。

    显然这是单调的,考虑双指针维护解决问题。

    B.

    我一开始把题意看成i|j==k的方案,结果一个小时之后才发现看挂了。

    最后才发现,其实原题意就是看错题意答案的前缀最大值,考虑维护子集的最大值和次大值,接着套上一个状压dp即可解决。

    附代码:

    A:

    #include<cstdio>
    int n,a[200050];
    bool mark[25];
    long long ans;
    void undo(int x){
        int cnt=0;
        while(x){
            if(x&1) mark[cnt]=false;
            ++cnt; x>>=1;
        }
        return ;
    }
    bool check(int x){
        int cnt=0;
        while(x){
            if((x&1)&&mark[cnt]) return false;
            ++cnt; x>>=1;
        }
        return true;
    }
    void ins(int x){
        int cnt=0;
        while(x){
            if(x&1) mark[cnt]=true;
            ++cnt; x>>=1;
        }
        return ;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        int st=0,en=0;
        while(st<=n){
            if(st!=0) undo(a[st]);
            ++st;
            while(en<n){
                if(check(a[en+1]))
                    ins(a[++en]);
                else break;
            }
            ans+=en-st+1;
        }
        printf("%lld
    ",ans);
        return 0;
    }

    B:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    struct node{
        int mins,id1;
        int smin,id2;
    }dp[262149];
    using std::min;
    using std::max;
    int n,a[262149];
    void merge(int i,int j){
        if(dp[i].mins<dp[j].mins){
            dp[i].smin=max(dp[i].mins,dp[j].smin);
            dp[i].id2=dp[i].mins>dp[j].smin?dp[i].id1:dp[j].id2;
            dp[i].mins=dp[j].mins; dp[i].id1=dp[j].id1;
        }
        else if(dp[i].smin<dp[j].mins&&dp[j].id1!=dp[i].id1)
            dp[i].smin=dp[j].mins,dp[i].id2=dp[j].id1;
        return ;
    }
    int main(){
        scanf("%d",&n);
        memset(dp,0,sizeof dp);
        for(int i=0;i<(1<<n);++i) scanf("%d",&a[i]);
        dp[0]=(node){a[0],0,-1,-1};
        for(int i=1;i<(1<<n);++i){
            if(dp[i].smin) continue;
            dp[i]=(node){a[i],i,-1,-1};
            for(int j=0;j<n;j++)
                if((1<<j)&i) merge(i,i^(1<<j));
        }
        int lans=-1;
        for(int k=1;k<(1<<n);k++){
            printf("%d
    ",lans=max(lans,dp[k].smin+dp[k].mins));
        }
        return 0;
    }

    C题不会,走了。

  • 相关阅读:
    C语言指针的一些题目
    PowerDesigner 物理数据模型(PDM)
    PowerDesigner概念数据模型 CDM
    加密狗原理介绍
    磐石加密狗NT88管理层API
    使用加密狗进行加密的一些策略
    让 PowerDesigner 支持 SQLite!
    防止用户重复登陆
    SQL Server里一些未公开的扩展存储过程
    14个数据库的设计技巧
  • 原文地址:https://www.cnblogs.com/JiuPleber/p/9817206.html
Copyright © 2011-2022 走看看