zoukankan      html  css  js  c++  java
  • Codeforces 549F Yura and Developers

    Description

    有一个长度为n的数组a,现在要找一个长度至少为2的子段,求出这一子段的和,然后减去最大值,然后对k取余结果为0。
    问这样的子段有多少个
    题面

    Solution

    考虑分治,普遍的做法就是用最大值分治:即找到最大值作为 (mid),然后 (solve(l,mid),solve(mid+1,r))
    但是这样做必须得保证每一次枚举 (mid-l)(r-mid) 中最小的一个才能保证复杂度,即启发式合并的复杂度 (O(n*logn))

    从上往下递归的话,每一次找最大值是一个复杂度瓶颈,考虑从下往上,每一次合并最大值即可

    这个过程可以不用递归实现,我们按照从小到大的顺序枚举 (a) 中的每一个数,并且维护分治区间 ([L,R]) 就可以达到这个效果
    ([L,R]) 的实际含义就是 (mid)([L,R]) 中的最大值

    考虑 (solve(l,r)) 怎么统计答案,我们枚举 (mid-l)(r-mid) 中较小的一个 (i),那么 (i) 的贡献就是在 ([l,mid]) 中与 (sum[i]) 相同的数的个数
    (sum) 是模 (k) 意义下的前缀和,对于每一个 (sum[i]) 我们开一个数组(维护相同前缀和出现的不同位置),二分出 ([l,mid]) 中出现的次数,就做完了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=300005;
    vector<int>S[1000005];
    int n,K,a[N],s[N],L[N],R[N],lis[N];ll ans=0;
    inline bool comp(int i,int j){return a[i]<a[j];}
    inline int query(int l,int r,int k){
    	if(l>r)return 0;
    	return upper_bound(S[k].begin(),S[k].end(),r)
    		-upper_bound(S[k].begin(),S[k].end(),l-1);
    }
    inline void solve(int mid){
    	int l=L[mid]+1,r=R[mid]-1;
    	if(mid-l<r-mid){
    		for(int i=l-1;i<mid;i++)
    			ans+=query(max(mid,i+2),r,(s[i]+a[mid])%K);
    	}
    	else{
    		for(int i=mid;i<=r;i++)
    			ans+=query(l-1,min(mid-1,i-2),(s[i]-a[mid]+K)%K);
    	}
    	R[L[mid]]=R[mid];L[R[mid]]=L[mid];
    }
    int main(){
      freopen("pp.in","r",stdin);
      freopen("pp.out","w",stdout);
      scanf("%d%d",&n,&K);
      for(int i=1;i<=n;i++){
    	  scanf("%d",&a[i]);
    	  s[i]=(s[i-1]+a[i])%K;
    	  L[i]=i-1;R[i]=i+1;
      }
      for(int i=0;i<=n;i++)S[s[i]].push_back(i),lis[i]=i;
      sort(lis+1,lis+n+1,comp);
      for(int i=1;i<=n;i++)a[lis[i]]%=K,solve(lis[i]);
      cout<<ans<<endl;
      return 0;
    }
    
    
  • 相关阅读:
    Java 8 lambda maxBy取最大/minBy取最小取平均值counting计数partitioningBy分隔/groupingBy分组
    mybatis xml参数传递详解
    java中判断字符串是否为纯数字,正则表达式判断
    OAuth 2.0 的四种方式
    Spring Boot 日志配置(超详细)
    SpringBoot基础系列-使用日志
    zuul动态配置路由规则,从DB读取
    TypeError: this.getOptions is not a function
    mysql索引类型和索引方法
    SpringBoot 处理异常的几种常见姿势
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8503763.html
Copyright © 2011-2022 走看看