zoukankan      html  css  js  c++  java
  • Codeforces Beta Round #91 (Div. 1 Only) A. luckSum(区间分块求解)

    这道题的主要解法在对1~100000000 中的luckNumber进行分块求和;

    例如, luckSum[0] = Sum[1,4]  luckSum[1] = Sum[5,7] luckSum[2] = Sum[8,44] ......................

    然后根据l,r 的区间跨度来求和;

    所在区间用一个int findUnder(int l)来求取;

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    typedef long long ll;
    
    const int maxn = 1e9;
    ll luckNumber[1500][2];
    ll luckSum[1500];
    
    void init(){
        int cnt=2;
        long long num;
        queue<long long> que; 
        
        luckNumber[0][0]=1;
        luckNumber[0][1]=4;
        luckNumber[1][0]=5;
        luckNumber[1][1]=7;
        
        que.push(4);
        que.push(7);
        
        while(!que.empty()){
            num = que.front();
            que.pop();
            
            if(num*10+4<=maxn) luckNumber[cnt][0] = luckNumber[cnt-1][1]+1,luckNumber[cnt++][1] = num*10+4,que.push(num*10+4);
            else break;
            
            if(num*10+7<=maxn) luckNumber[cnt][0] = luckNumber[cnt-1][1]+1,luckNumber[cnt++][1] = num*10+7,que.push(num*10+7);
            else break;
            
        }
        luckNumber[cnt][0]=luckNumber[cnt-1][1]+1;
        luckNumber[cnt][1]=4444444444;
        
        for(int i=0;i<cnt;i++){
            luckSum[i] = (luckNumber[i][1]-luckNumber[i][0]+1)*luckNumber[i][1];
            //cout<<luckSum[i]<<endl;
        }
        //cout<<cnt<<endl;
            
    }
    
    int findUnder(int l){
        
        for(int i=0;i<=1022;i++){
            if(l<=luckNumber[i][1]&&l>=luckNumber[i][0]) return i;
        }
        
    }
    
    int main(){
        init(); 
        int l,r,lSize,rSize;
        ll sum;
        scanf("%d%d",&l,&r);
        
        lSize = findUnder(l);
        rSize = findUnder(r);
        sum = 0;
        
        sum  = (min(luckNumber[lSize][1],(ll)r)-l+1)*luckNumber[lSize][1];
        for(int i=lSize+1;i<rSize;i++) sum+=luckSum[i];
        if(lSize!=rSize){
            sum += (r-luckNumber[rSize][0]+1)*luckNumber[rSize][1];
        }
        
        printf("%I64d
    ",sum);
        
        return 0;
    } 

    由cnt可以知道每次循环至多需要2^9次, 而至多只有5层循环 ,O(5*2^9);

  • 相关阅读:
    BM&EXCRT
    杨丰磊
    poj3613 Cow Relays
    详解KMP算法
    信息学作文
    恐怖的奴隶主(bob)
    玩具(toy)
    杯子 (glass)
    P3916 图的遍历
    《上帝给我一个任务,叫我牵一只蜗牛去散步》
  • 原文地址:https://www.cnblogs.com/yuanshixingdan/p/5481508.html
Copyright © 2011-2022 走看看