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
     
  • 相关阅读:
    Python中webbrowser的用法
    python爬虫笔记
    PHP yii2.0框架利用mpdf导出pdf
    PyQt5中QTableWidget设置列宽大小的几种方式
    看linux正在运行的服务用哪个命令?
    查看SELinux状态
    查看SMB服务器用户
    centOS7 下安装smb服务器
    (samba启动失败)smb.service: main process exited, code=exited, status=1/FAILURE
    Linux 操作日志
  • 原文地址:https://www.cnblogs.com/you-xiao-mang-ci/p/11285360.html
Copyright © 2011-2022 走看看