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\n",ans);
    return 0;
}

观看了大佬的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;
}

原文地址:https://www.cnblogs.com/TQCAI/p/8456397.html

时间: 2024-10-05 13:11:57

k倍区间的相关文章

【题集】k倍区间(抽屉原理)

例1:http://lx.lanqiao.cn/problem.page?gpid=T444 蓝桥杯 问题描述 给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间. 你能求出数列中总共有多少个K倍区间吗? 输入格式 第一行包含两个整数N和K.(1 <= N, K <= 100000) 以下N行每行包含一个整数Ai.(1 <= Ai <= 10000

第八届蓝桥杯-k倍区间

历届试题 k倍区间 时间限制:2.0s 内存限制:256.0MB 提交此题 问题描述 给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间. 你能求出数列中总共有多少个K倍区间吗? 输入格式 第一行包含两个整数N和K.(1 <= N, K <= 100000) 以下N行每行包含一个整数Ai.(1 <= Ai <= 100000) 输出格式 输出一个整

2017蓝桥杯第十题(k倍区间)

1 #include<iostream> 2 #include<stdio.h> 3 using namespace std; 4 const int N = 10010; 5 int n,c[N*3],a[N]; 6 int lowbit(int n){ 7 return n&(-n); 8 } 9 void change(int k,int pos){ 10 while(pos<=n){ 11 c[pos]+=k; 12 pos+=lowbit(pos); 13

51nod 1686 第k大区间

1686 第K大区间 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. 众数(统计学/数学名词)_百度百科 Input 第一行两个数n和k(1<=n<=100000,k<=n*(n-1)/2) 第二行n个数,0<=每个数<2^31 Output 一个数表示答案. Input示例 4 2 1 2 3 2 Output示例 2 /* 51nod 1686

51nod-1686 第K大区间(二分+尺取法)

题目链接: 第K大区间 基准时间限制:1 秒 空间限制:131072 KB 定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. Input 第一行两个数n和k(1<=n<=100000,k<=n*(n-1)/2) 第二行n个数,0<=每个数<2^31 Output 一个数表示答案. Input示例 4 2 1 2 3 2 Output示例 2 题意: 思路: 先把数组都离散为[1,n]的数,注意相等的;再二分答案t,check区间众数

1686 第K大区间

1686 第K大区间 时间限制:1 秒 空间限制:131072 KB 定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. 众数(统计学/数学名词)_百度百科 Input 第一行两个数n和k(1<=n<=100000,k<=n*(n-1)/2) 第二行n个数,0<=每个数<2^31 Output 一个数表示答案. Input示例 4 2 1 2 3 2 Output示例 2思路:二分答案t,统计众数出现次数大于等于t的区间有多少个. 枚

51 NOD 1685 第K大区间2 二分+BIT

题目描述: 定义一个长度为奇数的区间的值为其所包含的的元素的中位数. 现给出n个数,求将所有长度为奇数的区间的值排序后,第K大的值为多少. 样例解释: [l,r]表示区间的值 [1]:3 [2]:1 [3]:2 [4]:4 [1,3]:2 [2,4]:2 第三大是2 输入: 第一行两个数n和k(1<=n<=100000,k<=奇数区间的数量) 第二行n个数,0<=每个数<2^31 输出: 一个数表示答案. 题解: 二分答案t,统计中位数大于等于t的区间有多少个. 设a[i]为

uva 1567 - A simple stone game(K倍动态减法游戏)

题目链接:uva 1567 - A simple stone game 题目大意:给定K和N,表示一堆石子有N个,先手第一次可以取1~N-1个石子,取到最后一个石子的人胜利,单词每次操作时,取的石子数不能超过对手上一次取的石子数m的K倍.问先手是否可以必胜,可以输出最小的首次操作. 解题思路:这题想了一天,又是打表找规律,又是推公式的,楞是做不出来,后来在网上找到了一篇题解,将的很清楚,解题宝典 /******************* * K倍动态减法游戏 * 参考:http://www.cn

【51nod】 第K大区间2(二分+树状数组)

[51nod] 第K大区间2(二分+树状数组) 第K大区间2 ﹡    LH (命题人) 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 定义一个长度为奇数的区间的值为其所包含的的元素的中位数.中位数_百度百科 现给出n个数,求将所有长度为奇数的区间的值排序后,第K大的值为多少. 样例解释: [l,r]表示区间的值 [1]:3 [2]:1 [3]:2 [4]:4 [1,3]:2 [2,4]:2 第三大是2 Input 第一行两个数n和k(1<=n<=100000,k&l