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
     
  • 相关阅读:
    E. Paired Payment 题解(多维最短路)
    九峰与子序列 题解(dp+hash)
    魏迟燕的自走棋 题解(并查集+思维)
    unix学习资料
    Tomcat > Cannot create a server using the selected type
    myeclipse使用hibernate正向工程和逆向工程
    jira的破解
    jsp:useBean用法
    java一个多线程的经典例子
    head first系列PDF资源
  • 原文地址:https://www.cnblogs.com/you-xiao-mang-ci/p/11285360.html
Copyright © 2011-2022 走看看