此题应该算是开荒题了吧。。。
主要注意对于一个后缀的排名显然第一位是最重要的,然后对于两个不同的后缀第一位什么时候能相同呢?就是如果a<b那么在a后的后缀h,和在b后的后缀k依然是h<k的话那么就a=b就是可能的如果h>k那么必然有a<b
这样更具题目给的条件我们就把此题转化成了一个组合数学问题,
对于样例
第一个级别对应位置4,位置5的级别是4
第二级别对应位置3,位置4的级别是1
因为4>1,所以第一级别的字母一定是比第二级别的字母小的
然后这样一个一个推下去。看哪些相邻级别的字母能相同
然后问题就是一个插板问题了
首先一定会有总共25个版,每个版对应一个字母级别从左到右是a b c d .....,然后前面我们算出了一定会在某些地方插bannum个版,这些版是位置不变而且数目也不变的,就只能插在出现断层的字母之间,还剩下25-bannum个版,我们让这25-bannum个版插进n个字母中这应该是个很简单的组合问题了。插了这些版再插固定版所以答案就是
C(25-bannum n+25-bannum)
然后要写高精度。。。
开荒+高精度第一次写。。。所以我已经wa到麻木了。。。。。。然后终于过了。。。注意c(0,n)这个要特判对于很可能错
写得很多,大多数都是没用的,不过我只是拿来研究高精度了。。。其实还有很多地方需要完善,以后来弥补。。。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long ll;
const ll base = 1000000000;
const ll poww[10] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
struct Big_int
{
ll num[8000];
int cnt;
friend istream& operator>>(istream &in, Big_int &c)
{
char s[3000];
for (int i = 0; i < 3000; i++)
c.num[i] = 0;
scanf("%s", s+1);
int len = strlen(s+1);
c.cnt = (len-1)/ 9 + 1;
for (int i = 1; i <= len; i++)
{
c.num[(len - i) / 9 + 1] += (s[i] - '0')*poww[(len - i) % 9];
}
return in;
}
Big_int& operator=(ll a)
{
for (int i = 0; i <3000; i++)
num[i] = 0;
int tot = 1;
while (a)
{
num[tot] = a%base;
a /= base;
tot++;
}
cnt = tot - 1;
return *this;
}
Big_int& operator*=(ll a)
{
Big_int c;
c = 0;
for (int i = 1; i <= cnt; i++)
{
c.num[i]+= num[i] * a;
if (c.num[i]>base)
c.num[i + 1] += c.num[i] / base,
c.num[i] %= base;
}
if (c.num[cnt + 1])
cnt++;
while (c.num[cnt] > base)
{
c.num[cnt + 1] += c.num[cnt] / base,
c.num[cnt] %= base;
cnt++;
}
for (int i = 1; i <= cnt; i++)
num[i] = c.num[i];
return *this;
}
Big_int& operator/=(ll a)
{
for (int i = cnt; i >= 1; i--)
{
if (i - 1)
{
num[i - 1] += (num[i] % a)*base;
}
num[i] /= a;
}
while (num[cnt] == 0)
cnt--;
return *this;
}
friend bool operator>(Big_int &a, Big_int &b)
{
if (a.cnt == b.cnt)
{
for (int i = a.cnt; i >= 1; i--)
{
if (a.num[i] > b.num[i])
return true;
}
return false;
}
else
{
return a.cnt > b.cnt;
}
}
friend ostream& operator<<(ostream &out, Big_int &c)
{
if (c.num[0] == 1)
printf("-");
printf("%lld", c.num[c.cnt]);
for (int i = c.cnt - 1; i >= 1; i--)
{
printf("%09lld", c.num[i]);
}
return out;
}
};
Big_int operator*(Big_int &a, Big_int &b)
{
Big_int c;
c = 0;
if (b > a)
swap(a, b);
int get1 = 0, get2 = 0;
for (int i = 1; i <= b.cnt; i++)
{
int get1 = 0, get2 = 0;
for (int j = 1; j <= a.cnt+1; j++)
{
get2 = (a.num[j] * b.num[i]) / base;
c.num[i + j - 1] += ((a.num[j] * b.num[i]) % base)+get1;
if (c.num[i + j - 1] >=base)
{
get2 += c.num[i + j - 1] / base;
c.num[i + j - 1] %= base;
}
get1 = get2;
}
}
if (c.num[a.cnt + b.cnt])
c.cnt = a.cnt + b.cnt;
else
c.cnt = a.cnt + b.cnt-1;
while (c.num[c.cnt] > base)
{
c.num[c.cnt + 1] += c.num[c.cnt] / base;
c.num[c.cnt] %= base;
c.cnt++;
}
return c;
}
Big_int& operator-(Big_int &a, Big_int &b)
{
if (b > a)
{
swap(a, b);
a.num[0] = 1;
}
for (int i = 1; i <= b.cnt; i++)
{
if (a.num[i] < b.num[i])
{
a.num[i + 1]--;
a.num[i] += base;
}
a.num[i] -= b.num[i];
}
return a;
}
Big_int& operator+(Big_int &a, Big_int &b)
{
if (b > a)
swap(a, b);
for (int i = 1; i <= b.cnt; i++)
{
a.num[i] += b.num[i];
if (a.num[i] >= base)
{
a.num[i + 1] += (a.num[i] / base);
a.num[i] %= base;
}
}
if (a.num[a.cnt + 1])
a.cnt++;
return a;
}
int n, t;
void solve(int bannum)
{
ll all = n + 25- bannum;
ll num = 25 - bannum;
//ll num2 = all - num;
//if (num > num2)
// swap(num, num2);
Big_int a ;
a = all;
all--;
for (int i = 2; i <= num; i++)
{
a *= all;
all--;
}
//cout << a << endl;
if (bannum == 25)
{
printf("1\n");
}
else
{
for (int i = 1; i <= num; i++)
a /= i;
cout << a << endl;
}
}
int a[100020], pos[100020];
int main()
{
/*ll b = 31 * 30 * 29 * 28 * 27 * 26;
b /= 720;
cout << b << endl;
Big_int aa;
aa = 1;
for (int i = 31; i >= 26; i--)
aa *= i;
aa /= 720;
cout << aa << endl;*/
int t;
scanf("%d", &t);;
while (t--)
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n; i++)
pos[a[i]] = i;
int bannum = 0;
for (int i = 2; i <= n; i++)
if (pos[a[i - 1] + 1] > pos[a[i] + 1])
bannum++;
//cout << bannum << endl;
if (bannum > 25)
printf("0\n");
else
solve(bannum);
}
return 0;
}
指针版高精度。其实高精还是适合用指针写,不过不好调试。。。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll base = 100;
const ll bl = 2;
ll poww[10] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
struct Big_int
{
ll *num;
int cnt;
Big_int()
{
}
~Big_int()
{
delete []num;
}
Big_int(ll get,int kind)
{
if (kind == 1)
num = new ll[80000];
if (kind == 2)
num = new ll[8];
int i;
for ( i = 1; get; i++)
{
num[i] = get%base;
get /= base;
}
cnt = i-1;
}
friend istream& operator>>(istream &in, Big_int *c)
{
static char s[72000];
scanf("%s", s+1);
int len = strlen(s+1);
c->num = new ll[9*len];
c->cnt = len / bl + 1;
for (int i = 0; i <= c->cnt; i++)
c->num[i] = 0;
for (int i = 1; i <= len; i++)
{
c->num[(len - i) / bl + 1] += (s[i] - '0')*poww[(len - i) % bl];
}
if (c->num[c->cnt] == 0)
c->cnt--;
return in;
}
Big_int& operator*=(ll a)
{
ll get1 = 0, get2 = 0;
for (int i = 1; i <= cnt+1; i++)
{
if (i == cnt + 1)
num[i] = 0;
get1 = (num[i] * a) / base;
num[i] = (num[i] * a) % base+get2;
get2 = get1;
if (num[i] >= base&&i!=cnt+1)
{
get2 += num[i] / base;
num[i] %= base;
}
}
if (num[cnt + 1])
cnt++;
while (num[cnt] > base)
{
num[cnt + 1] = 0;
num[cnt + 1] += num[cnt] / base;
num[cnt] %= base;
cnt++;
}
return *this;
}
friend ostream& operator<<(ostream &out, Big_int *c)
{
printf("%lld", c->num[c->cnt]);
for (int i = c->cnt - 1; i >= 1; i--)
{
printf("%02lld", c->num[i]);
}
return out;
}
};
Big_int *qq,*pp,*lgl;
Big_int kk;
int main()
{
qq = new Big_int(20,1);
pp = new Big_int(20,1);
lgl = new Big_int(20, 1);
return 0;
}*/
再存一个自己写的高精度
//高精度
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long ll;
const ll base = 1000000000;
const ll poww[10] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
struct Big_int
{
ll num[8000];
int cnt;
friend istream& operator>>(istream &in, Big_int &c)
{
char s[3000];
for (int i = 0; i < 3000; i++)
c.num[i] = 0;
scanf("%s", s+1);
int len = strlen(s+1);
c.cnt = (len-1)/ 9 + 1;
for (int i = 1; i <= len; i++)
{
c.num[(len - i) / 9 + 1] += (s[i] - '0')*poww[(len - i) % 9];
}
return in;
}
Big_int& operator=(ll a)
{
for (int i = 0; i <3000; i++)
num[i] = 0;
int tot = 1;
while (a)
{
num[tot] = a%base;
a /= base;
tot++;
}
cnt = tot - 1;
return *this;
}
Big_int& operator*=(ll a)
{
Big_int c;
c = 0;
for (int i = 1; i <= cnt; i++)
{
c.num[i]+= num[i] * a;
if (c.num[i]>base)
c.num[i + 1] += c.num[i] / base,
c.num[i] %= base;
}
if (c.num[cnt + 1])
cnt++;
while (c.num[cnt] > base)
{
c.num[cnt + 1] += c.num[cnt] / base,
c.num[cnt] %= base;
cnt++;
}
for (int i = 1; i <= cnt; i++)
num[i] = c.num[i];
return *this;
}
Big_int& operator/=(ll a)
{
for (int i = cnt; i >= 1; i--)
{
if (i - 1)
{
num[i - 1] += (num[i] % a)*base;
}
num[i] /= a;
}
while (num[cnt] == 0)
cnt--;
return *this;
}
friend bool operator>(Big_int &a, Big_int &b)
{
if (a.cnt == b.cnt)
{
for (int i = a.cnt; i >= 1; i--)
{
if (a.num[i] > b.num[i])
return true;
}
return false;
}
else
{
return a.cnt > b.cnt;
}
}
friend ostream& operator<<(ostream &out, Big_int &c)
{
if (c.num[0] == 1)
printf("-");
printf("%lld", c.num[c.cnt]);
for (int i = c.cnt - 1; i >= 1; i--)
{
printf("%09lld", c.num[i]);
}
return out;
}
};
Big_int operator*(Big_int &a, Big_int &b)
{
Big_int c;
c = 0;
if (b > a)
swap(a, b);
int get1 = 0, get2 = 0;
for (int i = 1; i <= b.cnt; i++)
{
int get1 = 0, get2 = 0;
for (int j = 1; j <= a.cnt+1; j++)
{
get2 = (a.num[j] * b.num[i]) / base;
c.num[i + j - 1] += ((a.num[j] * b.num[i]) % base)+get1;
if (c.num[i + j - 1] >=base)
{
get2 += c.num[i + j - 1] / base;
c.num[i + j - 1] %= base;
}
get1 = get2;
}
}
if (c.num[a.cnt + b.cnt])
c.cnt = a.cnt + b.cnt;
else
c.cnt = a.cnt + b.cnt-1;
while (c.num[c.cnt] > base)
{
c.num[c.cnt + 1] += c.num[c.cnt] / base;
c.num[c.cnt] %= base;
c.cnt++;
}
return c;
}
Big_int& operator-(Big_int &a, Big_int &b)
{
if (b > a)
{
swap(a, b);
a.num[0] = 1;
}
for (int i = 1; i <= b.cnt; i++)
{
if (a.num[i] < b.num[i])
{
a.num[i + 1]--;
a.num[i] += base;
}
a.num[i] -= b.num[i];
}
return a;
}
Big_int& operator+(Big_int &a, Big_int &b)
{
if (b > a)
swap(a, b);
for (int i = 1; i <= b.cnt; i++)
{
a.num[i] += b.num[i];
if (a.num[i] >= base)
{
a.num[i + 1] += (a.num[i] / base);
a.num[i] %= base;
}
}
if (a.num[a.cnt + 1])
a.cnt++;
return a;
}
int n, t;
void solve(int bannum)
{
ll all = n + 25- bannum;
ll num = 25 - bannum;
//ll num2 = all - num;
//if (num > num2)
// swap(num, num2);
Big_int a ;
a = all;
all--;
for (int i = 2; i <= num; i++)
{
a *= all;
all--;
}
//cout << a << endl;
if (bannum == 25)
{
printf("1\n");
}
else
{
for (int i = 1; i <= num; i++)
a /= i;
cout << a << endl;
}
}
int a[100020], pos[100020];
int main()
{
/*ll b = 31 * 30 * 29 * 28 * 27 * 26;
b /= 720;
cout << b << endl;
Big_int aa;
aa = 1;
for (int i = 31; i >= 26; i--)
aa *= i;
aa /= 720;
cout << aa << endl;*/
int t;
scanf("%d", &t);;
while (t--)
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n; i++)
pos[a[i]] = i;
int bannum = 0;
for (int i = 2; i <= n; i++)
if (pos[a[i - 1] + 1] > pos[a[i] + 1])
bannum++;
//cout << bannum << endl;
if (bannum > 25)
printf("0\n");
else
solve(bannum);
}
return 0;
}