Molly's Chemicals(接頭辞と+マップの使用法、回答に直接対応)

タイトル:

この区間の合計がkの累乗になるような区間を見つけます

答え:

接頭辞と

次に、この条件を満たす式を見つけて、一度満たして、答えを1回増やします。

presum [i]-presum [j] = k ^ x;

しかし、列挙に直接移動すると、どうしてタイムアウトにならないのでしょうか。

だからただ合格

しかし、この式を次のように変更することができます

presum [i] = k ^ x + presum [j];

まず、この質問をいくつかの部分に分割します。最初の質問は、直接印刷できるk^xを見つけることです。

	for(int i=1;i<=64;i++){
		excel[0]=1;
		if(excel[i-1]<inf) excel[i]=excel[i-1]*k;

2番目の部分は、対応するものを見つけることです

k ^ x +presum[j]の数

この部分は、presume [i-1] + excel [j]によって、マップ内の各i-1に対応するすべてのjの合計を格納できます。背面にpresum [i]がある場合は、直接格納されます。後で確認してください。-1/1の場合は、何度もトラバースする必要はありません。保存するたびに逃げてください。

for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		for(int j=0;j<=64&&excel[j]<inf;j++){
			if(k==1||k==-1){
				if(k==-1) mp[presum[i-1]-1]++;
				mp[presum[i-1]+1]++;
				break;
			}
			else{
				mp[presum[i-1]+excel[j]]++;
			}
		}
		presum[i]=presum[i-1]+a[i];
		ans += mp[presum[i]];
	}

-1の場合の特文はありますか?

presum[i-1]-1とpresum[i-1]+1を直接保存するのはなぜですか?

これらの2つのケースでは、後で検索するだけで十分です(jは64回あります)

ACコード:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <map>
#include <string.h>
typedef long long ll;
using namespace std;
const int maxn = 1e5+10;
const ll inf = 1e15 + 10;
ll presum[maxn],a[maxn];
ll excel[maxn];
/*
首先用前缀和存数组,然后再
presum[j]-presum[i]=k^n;
k^n我打算用快速幂打表存储
presum[j]-presum[i]就看
需要用map,哪一部分???
*/
//unmap<ll ll>mp;
map<ll,ll>mp;

ll ksm(ll a,ll b){
	ll ans = 1;
	for(;b>0;b /=2 , a*= a){
		if(b % 2 != 0){
			ans *= a;
		}
	}
	return ans;
}

int main() {
	int n,k;
	ll ans=0;
	mp.clear();
	memset(excel, 0, sizeof(excel));
	memset(presum, 0, sizeof(presum));
	memset(a, 0, sizeof(a));
	scanf("%d%d",&n,&k);
	for(int i=1;i<=64;i++){
		excel[0]=1;
		if(excel[i-1]<inf) excel[i]=excel[i-1]*k;
//		if(k==1){
//			memset(excel , 1,sizeof(excel));
//			break;
//		}
//		if(k==-1){
//			for(int j=1;j<=maxn;j++){
//				excel[j]=-1;
//				j++;
//				excel[j]=1;
//			}
//			break;
//		}
//		excel[i]=ksm(k,i);
	}
	
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		for(int j=0;j<=64&&excel[j]<inf;j++){
			if(k==1||k==-1){
				if(k==-1) mp[presum[i-1]-1]++;
				mp[presum[i-1]+1]++;
				break;
			}
			else{
				mp[presum[i-1]+excel[j]]++;
			}
		}
		presum[i]=presum[i-1]+a[i];
		ans += mp[presum[i]];
	}
	printf("%lld",ans);
	return 0;
}

解決策があなたの考えをより明確にするなら、注意を払って行くことを忘れないでください!

おすすめ

転載: blog.csdn.net/weixin_60789461/article/details/122012621