牛客练习赛69 E 字串(哈希)
题目链接
题目大意
给出一个长度为n排列p
规定一个区间 [l,r] (l<=r) 是 fair 的,当且仅当区间中最小值等于 l 并且最大值等于 r
求 fair 区间的个数
题目思路
我不会正解
首先把每一个i值映射成\(base^i\)
遍历一边全排列
然后每次加上base[a[i]]减去base[i],求贡献,如果[l,r]满足条件,那么这一段区间的add值为0,
有点口胡,建议自己多多理解
注意要写mp[0]=1
ps:有大佬用随机数异或+异或前缀和是真的秀
代码
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define fi first
#define se second
#define debug printf(" I am here\n");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e6+5,inf=0x3f3f3f3f;
const ull mod=1e9+7;
const double eps=1e-10;
ull base[maxn];
int n,a[maxn];
unordered_map<ull,int> mp;
signed main(){
base[0]=1;
for(int i=1;i<=1e6;i++){
base[i]=base[i-1]*mod;
}
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
ll ans=0;
mp[0]=1;
ull add=0;
for(int i=1;i<=n;i++){
add=(ull)(add+base[a[i]]-base[i]);
ans+=mp[add];
mp[add]++;
}
printf("%lld\n",ans);
return 0;
}
不摆烂了,写题