Init
This commit is contained in:
136
ACMOJ-1018.cpp
Normal file
136
ACMOJ-1018.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
#include<iostream>
|
||||
#include<cstring>
|
||||
#include<algorithm>
|
||||
#include<cassert>
|
||||
#include<vector>
|
||||
#include<random>
|
||||
// #include<map>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
typedef pair<int,LL> SufType;
|
||||
const int maxn=1005;
|
||||
int N,K,a[maxn];
|
||||
bool used[maxn];
|
||||
vector<int> position,number;
|
||||
LL OuterPair[20][20],stk[20],Answer,TotalNotFixed,InnerPair[1<<14][20];
|
||||
int hsh[(1<<14)+1];
|
||||
int PreLength,SufLength;
|
||||
struct Hash_SufType2LongLong
|
||||
{
|
||||
const static int PoolSize=17297280*3;
|
||||
const static LL a=233331,b=19260817;
|
||||
LL Pool[PoolSize];
|
||||
int head[PoolSize],nxt[PoolSize],stv[PoolSize],CntV[PoolSize],PoolCnt=0;
|
||||
inline LL& operator[](const SufType &key)
|
||||
{
|
||||
const LL HashValue=(key.first*a+key.second+b)%PoolSize;
|
||||
// return Pool[HashValue];
|
||||
int p=head[HashValue];
|
||||
while(p)
|
||||
{
|
||||
if(stv[p]==key.first&&CntV[p]==key.second) return Pool[p];
|
||||
p=nxt[p];
|
||||
}
|
||||
PoolCnt++;
|
||||
nxt[PoolCnt]=head[HashValue];
|
||||
stv[PoolCnt]=key.first;
|
||||
CntV[PoolCnt]=key.second;
|
||||
head[HashValue]=PoolCnt;
|
||||
return Pool[PoolCnt];
|
||||
}
|
||||
}SufData;
|
||||
void dfs(int dep,LL CurrentPair,int st)
|
||||
{
|
||||
if(dep==PreLength)
|
||||
{
|
||||
Answer+=SufData[SufType(((1<<TotalNotFixed)-1)^st,K-CurrentPair)];
|
||||
return;
|
||||
}
|
||||
int valid=((1<<TotalNotFixed)-1)^st;
|
||||
for(;valid;valid-=valid&(-valid))
|
||||
{
|
||||
int i=hsh[valid&(-valid)];
|
||||
if((st&(1<<i))==0
|
||||
&&CurrentPair+InnerPair[st][i]+OuterPair[dep][i]<=K
|
||||
&&!(K>CurrentPair+(TotalNotFixed-dep)*(TotalNotFixed-dep-1)/2+(TotalNotFixed-dep)*(N-TotalNotFixed+dep)))
|
||||
{
|
||||
stk[dep]=number[i];
|
||||
dfs(dep+1,CurrentPair+InnerPair[st][i]+OuterPair[dep][i],st|(1<<i));
|
||||
}
|
||||
}
|
||||
}
|
||||
int main()
|
||||
{
|
||||
#ifdef local
|
||||
freopen("pro.in","r",stdin);
|
||||
#endif
|
||||
scanf("%d%d",&N,&K);
|
||||
for(int i=1;i<=N;i++)
|
||||
{
|
||||
scanf("%d",&a[i]);
|
||||
used[a[i]]=true;
|
||||
if(a[i]==0) position.push_back(i);
|
||||
assert(0<=a[i]&&a[i]<=N);
|
||||
}
|
||||
LL AlreadyHave=0;
|
||||
for(int i=1;i<=N;i++)
|
||||
for(int j=i+1;j<=N;j++)
|
||||
if(a[i]!=0&&a[j]!=0&&a[i]>a[j])
|
||||
AlreadyHave++;
|
||||
for(int i=1;i<=N;i++)
|
||||
if(!used[i])
|
||||
number.push_back(i);
|
||||
TotalNotFixed=position.size();
|
||||
for(int i=0;i<TotalNotFixed;i++)
|
||||
{
|
||||
const int pos=position[i];
|
||||
for(int j=0;j<TotalNotFixed;j++)
|
||||
{
|
||||
const int num=number[j];
|
||||
for(int k=1;k<=N;k++)
|
||||
if((a[k]!=0&&k<pos&&a[k]>num)||(a[k]!=0&&k>pos&&a[k]<num))
|
||||
OuterPair[i][j]++;
|
||||
}
|
||||
}
|
||||
for(int st=0;st<(1<<TotalNotFixed);st++)
|
||||
for(int p=0;p<TotalNotFixed;p++)
|
||||
for(int i=0;i<TotalNotFixed;i++)
|
||||
if((st&(1<<i))&&number[i]>number[p])
|
||||
InnerPair[st][p]++;
|
||||
if(K>AlreadyHave+TotalNotFixed*(TotalNotFixed-1)/2+TotalNotFixed*(N-TotalNotFixed))
|
||||
{
|
||||
puts("0");
|
||||
return 0;
|
||||
}
|
||||
for(int i=0;i<TotalNotFixed;i++) hsh[1<<i]=i;
|
||||
SufLength=(TotalNotFixed+1)/2;
|
||||
PreLength=TotalNotFixed-SufLength;
|
||||
const int FullStatus=(1<<TotalNotFixed)-1;
|
||||
for(int st=0;st<(1<<TotalNotFixed);st++)
|
||||
{
|
||||
if(__builtin_popcount(st)==SufLength)
|
||||
{
|
||||
const int PreStatus=FullStatus^st;
|
||||
int p[10],pcnt=0;
|
||||
for(int i=0;i<TotalNotFixed;i++)
|
||||
if(st&(1<<i))
|
||||
p[pcnt++]=i;
|
||||
assert(pcnt==SufLength);
|
||||
do
|
||||
{
|
||||
LL tmp=0,AlreadyProced=0;
|
||||
for(int i=0;i<SufLength;i++)
|
||||
{
|
||||
tmp+=OuterPair[TotalNotFixed-SufLength+i][p[i]];
|
||||
tmp+=InnerPair[PreStatus][p[i]];
|
||||
tmp+=InnerPair[AlreadyProced][p[i]];
|
||||
AlreadyProced|=1<<p[i];
|
||||
}
|
||||
SufData[SufType(st,tmp)]++;
|
||||
} while (next_permutation(p,p+SufLength));
|
||||
}
|
||||
}
|
||||
dfs(0,AlreadyHave,0);
|
||||
printf("%lld\n",Answer);
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user