zoukankan      html  css  js  c++  java
  • 经典问题:查询有多少段区间和等于k值

    题目连接
    题意:在大小为1e5以内的数组求存在多少个区间和的值等于k的次方
    这种题很经常见,总是想着用两个for循环解决,但是一定会超时。
    题解:算出前缀和,使用map去查找mp[sum[i+1]-tmp]的个数,加起来就是答案,这样复杂度在O(n)加上mp的查找时间,基本上不会超时

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double db;
    typedef pair<int,int> pii;
    typedef vector<int> vi;
    #define de(x) cout << #x << "=" << x << endl
    #define rep(i,a,b) for(int i=a;i<(b);++i)
    #define all(x) (x).begin(),(x).end()
    #define sz(x) (int)(x).size()
    #define pb push_back
    #define fi first
    #define se second
    const int N = 1e5+5;
    const ll eps = 1e15;
    ll a[N];
    ll sum[N];
    map<ll,int>mp;
    int main()
    {
    	ll n,k,i,j;
    	ll tmp=1;
    	ll ans=0;
    	scanf("%lld%lld",&n,&k);
    	sum[0]=0;
    	for(i=1;i<=n;i++) {scanf("%lld",&a[i]);sum[i]=sum[i-1]+a[i];}
    	for(i=0;i<n;i++)
    	{
    		mp[sum[i]]++;
    		tmp=1;
    		while(tmp<eps&&k!=-1&&k!=1)
    		{
    			if(mp[sum[i+1]-tmp]!=0) ans+=mp[sum[i+1]-tmp];
    			tmp=tmp*k;
    		}
    		if(k==-1)
    		{
    			if(mp[sum[i+1]-1]!=0) ans+=mp[sum[i+1]-1];
    			if(mp[sum[i+1]+1]!=0) ans+=mp[sum[i+1]+1];
    		}
    		else if(k==1)
    		{
    			if(mp[sum[i+1]-1]!=0) ans+=mp[sum[i+1]-1];
    		}
    	}
    	cout<<ans<<endl;
    } 
    
  • 相关阅读:
    cmake
    docker
    rust
    linux
    FPGA
    visual studio
    win+R
    word文档的导出(用freemarker模板导出)(桃)
    iconfont的引入方法
    jquery 日期插件
  • 原文地址:https://www.cnblogs.com/q1076452761/p/7710039.html
Copyright © 2011-2022 走看看