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;
    }
    
    
  • 相关阅读:
    Delphi公用函数单元
    Delphi XE5 for Android (十一)
    Delphi XE5 for Android (十)
    Delphi XE5 for Android (九)
    Delphi XE5 for Android (八)
    Delphi XE5 for Android (七)
    Delphi XE5 for Android (五)
    Delphi XE5 for Android (四)
    Delphi XE5 for Android (三)
    Delphi XE5 for Android (二)
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8503763.html
Copyright © 2011-2022 走看看