zoukankan      html  css  js  c++  java
  • Codeforces Round #104 (Div. 1) D Lucky Pair

    题目链接:Lucky Pair
    题意:只含有 4 和 7 的数字为幸运数字,给一个长度为 n 的序列,问有多少对互不相交的子区间,满足两个区间中没有相同的幸运数字。
    题解:大致做法比较容易想,但是细节有点多有点杂,几乎是在别人题解帮助下完成的。所有区间组合的个数为C(n,4)+2×C(n,3)+C(n,2),然后计算不合法的区间对数。最多只有 1000 个幸运数字,枚举第二个区间所包含的最左边的幸运数字 i,接着枚举第二个区间最右边的幸运数字 j,找到在第二个区间前面相同的幸运数字的位置 pos,找到在 set 中的 pos 前后位置 L、R,并把 pos 存入 set 中,不合法情况便是第一个区间包含 pos 不包含 L 和 R。分情况讨论第一个区间右端点和第二个区间左端点之间是否有幸运数字进行计算。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef unsigned long long LL;
    
    LL n,cnt,ans,tot;
    LL a[100005],pos[100005],pre[100005];
    
    LL C(LL x,LL y){
        if(y==2) return x*(x-1)/2;
        if(y==3) return x*(x-1)/2*(x-2)/3;
        if(y==4) return (x-3)*(x-2)/2*(x-1)/3*x/4;
    }
    
    bool islucky(LL x){
        while(x){
            if(x%10!=4&&x%10!=7)
                return false;
            x/=10;
        }
        return true;
    }
    int main(){
        scanf("%lld",&n);
        pos[0]=0;
        ans=C(n,4)+C(n,3)*2+C(n,2);
        for(LL i=1;i<=n;i++){
            scanf("%d",&a[i]);
            if(islucky(a[i])){
                pos[++cnt]=i;
                for(LL j=1;j<cnt;j++){
                    if(a[pos[j]]==a[pos[cnt]])
                        pre[cnt]=j;
                }
            }
        }
        pos[cnt+1]=n+1;
        for(LL i=2;i<=cnt;i++){
            set<LL> s;
            s.insert(0);
            LL temp=0;
            for(LL j=i;j<=cnt;j++){
                if(pre[j]<i){
                    LL k=pre[j];
                    while(k){
                        set<LL>::iterator L,R;
                        L=R=s.lower_bound(pos[k]);
                        L--;
                        if(R!=s.end()){
                            temp+=(pos[k]-(*L)) * ((*R)-pos[k]) * (pos[i]-pos[i-1]);
                        }
                        else{
                            temp+=(pos[k]-(*L)) * (pos[i-1]-pos[k]) * (pos[i]-pos[i-1]);
                            temp+=(pos[k]-(*L)) * C(pos[i]-pos[i-1]+1,2);
                        }
                        s.insert(pos[k]);
                        k=pre[k];
                    }
                }
                ans-=temp*(pos[j+1]-pos[j]);
            }
        }
        printf("%lld
    ",ans);
    
        return 0;
    }
  • 相关阅读:
    JQuery学习
    前端Web APIs 二
    前端Web APIS
    Swift 函数式数据结构
    JAVA 四大域对象总结
    Java 访问 C++ 方法:JavaCPP
    写Java也得了解CPU–CPU缓存
    Servlet使用注解标注监听器(Listener)
    Java使用Fork/Join框架来并行执行任务
    Linux学习之让进程在后台可靠运行的方法详解
  • 原文地址:https://www.cnblogs.com/N-Psong/p/10263830.html
Copyright © 2011-2022 走看看