(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
Catalog
Problem:Portal传送门
原题目描述在最下面。
问有多少段区间值的和是k的指数倍。
Solution:
先做前缀和,然后顺序遍历,然后map记录当前位前面的前缀和的出现次数,枚举k的指数求和。
一眼思路的sb题,改呀改呀结果tle再101组,心态都炸了。听yx特判一下a了,1965ms.然后一看别人的代码都是用的map,尝试性的试了一下,居然过了,而且1387ms。????
wtf??不是说unordered_map比map快吗??不行我得测试一下。文章末尾附上我测试两个map的效率。
AC_Code:
map: 1387ms
unordered_map+特判: 1965ms
#include<bits/stdc++.h>
#define mme(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
const int MXN = 1e5+7;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;
int n;
LL k;
LL ar[MXN], pre[MXN], pw[MXN], num[MXN], br[MXN];
map<LL,LL>mp;
template<typename T>
inline void read(T &x){
x = 0;int f=0;char ch=getchar();
while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
x=f?-x:x;
}
template<typename T>inline T mabs(T x){return (x < 0 ? -x : x);}
int main(){
int top;
while(~scanf("%d%lld", &n, &k)){
LL cnt = 0, sum = 0;
pre[0] = 0;
for(int i = 1; i <= n; ++i){
scanf("%lld", &ar[i]);
br[i] = ar[i];
sum += mabs(ar[i]);
pre[i] = pre[i-1] + ar[i];
}
pw[0] = 1;
for(int i = 1; ; ++i){
pw[i] = pw[i-1] * k;
top = i;
if(k == 1LL && pw[i] == 1LL)break;
if(top>=48||mabs(pw[i])>sum)break;
}
sort(pw,pw+top);
top = unique(pw,pw+top)-pw;
mp.clear();
for(int i = 1; i <= n; ++i){
for(int j = 0; j < top; ++j){
cnt += mp[pre[i]-pw[j]];
if(pw[j] == pre[i])cnt++;
}
++mp[pre[i]];
}
printf("%lld\n", cnt);
}
return 0;
}
Problem Description:
map与unordered_map效率测试
unordered_map 480ms
map 700ms
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
unordered_map<LL,LL>mp1;
map<LL,LL>mp2;
int main(){
int n = 2e4;
for(int i = 1, x; i < n; ++i){
LL tmp;
for(LL j = 1; j < 50; ++j){
x = rand();
tmp = mp1[x];
}
++mp1[x];
}
return 0;
}
unordered_map 51ms
map 40ms
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
unordered_map<LL,LL>mp1;
map<LL,LL>mp2;
int main(){
int n = 1e7;
for(int i = 1, x; i < n; ++i){
x=rand();
mp1.find(x);
}
return 0;
}