F. The Number of Subpermutations 题解(异或hash维护全排列)
题目链接
题目思路
这种有关全排列的问题大多都是异或前缀和求解
所以我们可以枚举 1的位置。每次向左/右搜,往一个方向搜的时候记录扫到的最大值,当作排列的长度(最大
值),在判断这个子串是否合法就行了。
代码
#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=3e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-6;
mt19937 rnd(time(0));
int n;
int a[maxn];
ll pre[maxn];
ll ha[maxn],base[maxn];
ll ans;
void cal(){
for(int i=1;i<=n;i++){
pre[i]=ha[a[i]]^pre[i-1];
}
for(int i=1,j=1;i<=n;i++){
if(a[i]==1){
j=1;
}else{
j=max(j,a[i]);
if(i>=j&&(pre[i]^pre[i-j])==base[j]){
ans++;
}
}
}
}
signed main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
ha[i]=rnd();
base[i]=(base[i-1]^ha[i]);
}
cal();
reverse(a+1,a+1+n);
cal();
for(int i=1;i<=n;i++){
if(a[i]==1) ans++;
}
printf("%lld\n",ans);
return 0;
}
不摆烂了,写题