D. Nastya and a Game【思維】
阿新 • • 發佈:2019-01-03
題意:給定一個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; }