zoukankan      html  css  js  c++  java
  • jzoj 2644. 数列

    给你一个长度为N的正整数序列,如果一个连续的子序列,子序列的和能够被K整

    除,那么就视此子序列合法,求原序列包括多少个合法的连续子序列?

    对于一个长度为8的序列,K=4的情况:2, 1, 2, 1, 1, 2, 1, 2 。它的答案为6,子序列

    是位置1->位置8,2->4,2->7,3->5,4->6,5->7。

    Input

    第一行:T,表示数据组数

    对于每组数据:

    第一行:2个数,K,N

    第二行:N个数,表示这个序列

    Output

    共T行,每行一个数表示答案

     
    简单数论加排序。。。
    我们使用前缀和存储。(即从1到x的序列和)
    然后,我们要找可以被k整除的区间和,
    就存在S1 < S2
    使满足S1≡S2(mod k)
    根据同余,有
    (S1-S2)≡0(mod k)
    也就是,当S1和S2模k余数相等,就可以组成被k整除的区间。
    可以把前缀和模k,然后排序,进行组合(不是高中那个,小学学的连线法就可以。。。)
    或者用桶装起来,ans+=t*(t-1)/2
    记住一定要把所有余数为0的单独加入ans,他很特殊
    #include<bits/stdc++.h>
    using namespace std;
    
    int sum[50500],k,t,n;
    
    int main(){
        scanf("%d",&t);
        for(int o=1;o<=t;o++){
            scanf("%d%d",&k,&n);
            sum[0]=0;
            for(int i=1;i<=n;i++){
                scanf("%d",&sum[i]);
                sum[i]=(sum[i]+sum[i-1])%k;
            }
            sort(sum+1,sum+1+n);
            int tt=0;
            sum[0]=-10086;
            int ans=0;
            for(int i=1;i<=n;i++){
                if(sum[i]==0)ans++;
                if(sum[i]==sum[i-1]){
                    tt++;
                    ans+=tt;
                }
                else tt=0;
            }
            printf("%d
    ",ans);
        }
        
        
        return 0;
    }
    View Code
     
  • 相关阅读:
    SQL应用初级指南
    XML 文档的基本操作
    SQL中单引号的转义
    C# (输入输出流)
    C# 文件与目录的基本操作(System.IO)
    数据库对象命名
    .Net 中的反射(反射特性) Part.3 (转载)
    C# 中的委托和事件(详解)
    SQL Server TransactSQL 编程
    Brush 色谱
  • 原文地址:https://www.cnblogs.com/you-xiao-mang-ci/p/11285360.html
Copyright © 2011-2022 走看看