1. 程式人生 > >D. Nastya and a Game【思維】

D. Nastya and a Game【思維】

題意:給定一個Arr[n],求滿足multipul[L,R]/sum[L,R]==k的區間個數

思路:對於a[i]==1的情況,因為對multipul是沒有影響的,隻影響L,R。那麼對於連續的區間1我們就可以跳,只要sum[L,R]∈[sum/multiple,sum/multiple+ lenof[1] ]。根據資料有multipul不會超過2e18。那麼根據以上的做法,因為每次乘的數都是≥2的,第二層while迴圈的次數不會超過61次。複雜度為O(60*n);

#include<bits/stdc++.h>
#define PI acos(-1.0)
#define pb push_back
#define F first
#define S second
using namespace std;
typedef long long ll;
const int N=2e5+5;
ll a[N],sum[N],jump[N],ans=0;
int main(void){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    ll n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++)   cin>>a[i];
    for(int i=1;i<=n;i++)   sum[i]=sum[i-1]+a[i];
    jump[n]=n;
    jump[n+1]=n+1;
    for(int i=n-1;i>=1;--i){
        if(a[i]==1) jump[i]=jump[i+1];
        else    jump[i]=i;
    }
    for(int i=1;i<=n;i++){
        ll mul=1;
        int j=i;
        int last=i;
        while(j<=n&&(ll)2e18/a[j]>=mul){
            /// last to j
            mul*=a[j];
            ll presum=sum[j]-sum[i-1];
//            if(j==i&&mul/presum==k)    ans++;
            last=j;
            j=jump[j+1];
            if(mul%k==0&&mul/k>=presum&&mul/k<=presum+j-last-1)ans++;
//            cout <<last<<" "<<j <<endl;
        }
    }
    cout << ans << endl;

    return 0;
}