zoukankan      html  css  js  c++  java
  • k倍区间

    用前缀和来求区间和,然后用一个二重循环穷举,但是因为问题规模为100000,所以超时(28分)

    超时代码:

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 100010
    #define MAX 0x06FFFFFF
    #define V vector<int>
    #define ll long long
    
    using namespace std;
    
    ll sum[LEN]; 
    
    int main(){
    //    freopen("D:/CbWorkspace/blue_bridge/k倍区间.txt","r",stdin);
        int i,j,n,k,ans=0;
        I("%d%d",&n,&k);
        FF(i,n){
            I("%d",&j);
            sum[i+1]=sum[i]+j;
        }
        for(i=1;i<=n;i++){
            for(j=i;j<=n;j++){
                int t=(sum[j]-sum[i-1]);
                if((sum[j]-sum[i-1])%k==0)
                    ans++;
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code

    观看了大佬的AC代码,终于明白怎么回事了。一句话, 计算前缀和然后取余k, 如果前i项和取余k与前j项和取余k后相同,那么i到j这个区间和为k的倍数

    注意ans,cnt,sum都要开 long long

    AC代码:

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 100010
    #define MAX 0x06FFFFFF
    #define V vector<int>
    #define ll long long
    
    using namespace std;
    
    ll sum[LEN]; 
    ll cnt[LEN];
    
    int A(int n,int m){
        int a=1;
        while(m){
            a*=n--;
            m--;
        }
        return a;
    }
    
    int C(int n,int m){
        int c=A(n,m);
        while(m){
            c/=m--;
        }
        return c;
    }
    
    int main(){
    //    freopen("D:/CbWorkspace/blue_bridge/k倍区间.txt","r",stdin);
        int i,j,n,k;
        ll ans=0;
        I("%d%d",&n,&k);
        FF(i,n){
            I("%d",&j);
            sum[i+1]=sum[i]+j;
        }
        cnt[0]=1;
        F(i,1,n+1){
            cnt[sum[i]%k]++;
        }
        FF(i,k){
            if(cnt[i]) ans+=cnt[i]*(cnt[i]-1)/2;    //C(n,2)
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    Generate SQL from Excel
    ASP.NET Web API系列教程目录
    进阶篇:以IL为剑,直指async/await
    30分钟?不需要,轻松读懂IL
    进程简介
    二维码详解
    通过IL分析C#中的委托、事件、Func、Action、Predicate之间的区别与联系
    我是一个线程
    ServiceLocator 简单示例(转)
    特性(C#)
  • 原文地址:https://www.cnblogs.com/TQCAI/p/8456397.html
Copyright © 2011-2022 走看看