很有思维的一道题

这个题的题面非常简单,出题人很友好,没有搞什么奇怪的背景,(卡农(P3214)的作者看看人家),所以理解题面就是:

一句话题意:

给定一个长度为 \(n\) 的数列,求这个数列是在其全排列中的排名是多少,输出排名 \(mod\) \(m\) 的结果。

赵小兵同学:这不就是个康托展开嘛,看我A掉这个大水题。

于是,他打出了下面这个程序:


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x7f7f7f7f7f
const int one = 1e7+10;
inline void openfile()
{freopen("t.txt","r",stdin);}
namespace zxb
{
int tree[1000005];
int n;
inline int lowbit(int x)
{
return x&-x;
}
inline void update(int x,int y)
{
while(x<=n){
tree[x]+=y;
x+=lowbit(x);
}
}
inline int query(int x)
{
int sum=0;
while(x)
{
sum+=tree[x];
x-=lowbit(x);
}
return sum;
}
int mod;
int jc[1000005];
int a[1000005];
inline short main()
{
//openfile();
jc[0] = jc[1] = 1;
cin >> n >> mod;
for(int i=1;i<=n;i++)
{
jc[i]=(jc[i-1]*i)%mod;
update(i,1);
}
int ans = 0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
ans=(ans+((query(a[i])-1)*jc[n-i]) % mod) % mod;
update(a[i],-1);
}
cout<<ans +1<<endl;
return 0;
}
}
signed main() { return zxb::main();}

然后。。。

赵小兵同学翻车记录

旁边的 \(C\) 君看不下去了,转眼就打了一个暴力算法,并对赵小兵同学发来了鄙视

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x7f7f7f7f7f
const int one = 1e7+10;
inline void openfile()
{freopen("t.txt","r",stdin);}
inline int get()
{
int s = 0,f = 1;
register char ch = getchar();
while(!isdigit(ch))
{
if(ch == '-') f= -1;
ch = getchar();
}
while(isdigit(ch))
{
s = s* 10 + ch - '0';
ch = getchar();
}
return s * f;
}
namespace xin
{
int a[one],b[one];
int mod,n;
inline bool comp()
{
for(register int i=1;i<=n;++i)
if(a[i] != b[i])
return false;
return true;
}
inline short main()
{
// openfile();
n = get(); mod = get();
for(register int i=1;i<=n;++i) a[i] = get(),b[i] = a[i];
sort(a+1,a+1+n);
int cnt = 1;
while(next_permutation(a+1,a+n+1))
{
cnt++;
if(comp() == 1)
{
cout<<cnt % mod<<endl;
return 0;
}
}
return 0;
}
}
signed main() { return xin::main();}

\(C\) 君的暴力记录\(C\) 君的暴力记录

\(C\) 君整整比赵小兵同学多了一倍的分数,这时候,坐在一旁的 \(XIN\) 同学看不下去了,但 \(XIN\) 同学一时间也无法想出正解,但是经过 \(XIN\) 同学为期 \(3\) 天的不懈奋斗,终于 \(A\) 掉了这个题目:

赵小冰和 \(C\) 君都想要知道他的思路, \(XIN\) 同学开始讲到:

首先,要考虑每一个数位的贡献值,其实赵小兵同学的第一想法是不错的,但是只能说是不对,因为这个题目存在重复,也存在模数为合数的时候,所以康托展开就不管用了,所以要考虑别的想法,发现全排列就和本身的字典序有关,之后得出计算式:

\[w \cdot \frac{(n-i)!}{\Pi \ {cnt[j]!}}
\]

$cnt $ 就是从 \(i\) 到 $n $ 中 \(j\) 所出现的个数

但是问题就又来了,合数应该怎么处理呢???

最先考虑费马小定理:

\[a^{p-1}≡1 (mod\ p)
\]

可是,模数为合数啊,所以考虑扩展欧几里的求出逆元:

inline void exgcd(int a,int b,int &x,int &y)
{
if(!b) { x = 1; y = 0; return;}
exgcd(b,a%b,y,x);
y -= a / b * x;
}
inline int get_inv(int x,int p)
{
int a,b;
exgcd(x,p,a,b);
return (a % p + p) % p;
}

之后可以用树状数组在 \(log\) 的时间复杂度的情况下求出区间最小值:

namespace xin_bit
{
int s[maxn];
inline int lowbit(int x)
{return x & -x;}
inline void add(int x,int val)
{
while(x <= maxn)
{
s[x] += val;
x += lowbit(x);
}
}
inline int query(int x)
{
register int ret = 0;
while(x)
{
ret += s[x];
x -= lowbit(x);
}
return ret;
}
}

之后来一点小小的转移,将因子分解,之后再合并,最后就可以按照计算式求出本题的答案了。

慷慨的 \(XIN\) 还放出了代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e6+10;
namespace xin_io
{
inline int get()
{
int s =0 ,f = 1;
register char ch = getchar();
while(!isdigit(ch))
{
if(ch == '-') f= -1;
ch = getchar();
}
while(isdigit(ch))
{
s = s *10 + ch - '0';
ch = getchar();
}
return s * f;
}
inline void write(int x)
{
if(x < 0) putchar('-'),x = -x;
if(x > 9) write(x/10);
putchar(x % 10 + '0');
}
}
using xin_io::get; using xin_io::write;
inline void openfile()
{freopen("t.txt","r",stdin);}
namespace xin_bit
{
int s[maxn];
inline int lowbit(int x)
{return x & -x;}
inline void add(int x,int val)
{
while(x <= maxn)
{
s[x] += val;
x += lowbit(x);
}
}
inline int query(int x)
{
register int ret = 0;
while(x)
{
ret += s[x];
x -= lowbit(x);
}
return ret;
}
}
namespace xin
{
#define m(c) cout<<sizeof(c) / (1 << 20) << "MB"<<endl
#define min(a,b) (a) < (b) ? (a) : (b)
#define max(a,b) (a) > (b) ? (a) : (b)
int mod;
int n,m;
bool number[maxn];
int prime[maxn];
int i,j,count=0;
inline void xin_shai(int N)
{
memset(number,true,sizeof(number));
for(i=2;i<=N;i++)
{
if(number[i])
prime[count++]=i;
for(j=0;j<count and prime[j]*i<=N;j++)
{
number[prime[j]*i]=false;
if(i%prime[j]==0)
break;
}
}
}
inline void exgcd(int a,int b,int &x,int &y)
{
if(!b) { x = 1; y = 0; return;}
exgcd(b,a%b,y,x);
y -= a / b * x;
}
inline int get_inv(int x,int p)
{
int a,b;
exgcd(x,p,a,b);
return (a % p + p) % p;
}
int cnt[110],link[110][maxn];
int rec1[maxn],rec2[maxn];
int temp,a[maxn],fac[maxn],num_fac = 0;
inline void cont(int &x,int val)
{
for(register int i=1;i<=num_fac;++i)
{
register int zhuan = fac[i];
while(!(x % zhuan))
x/=zhuan,cnt[i] += val;
}
}
inline int get_num()
{
int ret = 1;
for(register int i=1;i<=num_fac;++i)
ret = (ret * link[i][min(rec2[i],cnt[i])] ) % m;
return ret;
}
inline int work()
{
int ans = 0,ret = 1;
rec1[a[n]] = 1; xin_bit::add(a[n],1);
for(register int i=n-1;i>=1;--i)
{
int zhuan = n - i;
cont(zhuan,1);
ret *= zhuan; ret %= m;
zhuan = ++rec1[a[i]];
cont(zhuan,-1);
ret = (ret * get_inv(zhuan,m) + m) % m;
xin_bit::add(a[i],1);
zhuan = get_num();
ans += (ret % m * xin_bit::query(a[i] - 1) % m * zhuan % m + m ) % m;
ans %= m;
}
return ++ans;
}
inline short main()
{
openfile();
n = get(); m = get(); temp = m;
for(register int i=1;i<=n;++i) a[i] = get();
for(register int i=2;i<=sqrt(temp);++i)
if(temp % i == 0)
{
fac[++num_fac] = i;
link[num_fac][0] = 1;
for(register int j=1;j<=maxn;++j)
link[num_fac][j] = link[num_fac][j-1] * i % m,rec2[num_fac] ++;
while(temp % i == 0)temp /= i;
}
if(temp > 1)
{
fac[++num_fac] = temp;
link[num_fac][0] = 1;
for(register int j=1;j<=maxn;++j)
link[num_fac][j] = link[num_fac][j-1] * temp % m,rec2[num_fac]++;
}
int ans = work() % m;
write(ans);
putchar('\n');
return 0;
}
}
signed main() {return xin::main();}

[POI2008]PER的更多相关文章

  1. [BZOJ1112][POI2008]砖块Klo

    [BZOJ1112][POI2008]砖块Klo 试题描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另 ...

  2. [bzoj1122][POI2008]账本BBB

    1122: [POI2008]账本BBB Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 402  Solved: 202[Submit][Status ...

  3. BZOJ 1113: [Poi2008]海报PLA

    1113: [Poi2008]海报PLA Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1025  Solved: 679[Submit][Statu ...

  4. BZOJ 1116: [POI2008]CLO

    1116: [POI2008]CLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 922  Solved: 514[Submit][Status][ ...

  5. BZOJ 1112: [POI2008]砖块Klo

    1112: [POI2008]砖块Klo Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1736  Solved: 606[Submit][Statu ...

  6. BZOJ 1124: [POI2008]枪战Maf

    1124: [POI2008]枪战Maf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 617  Solved: 236[Submit][Status ...

  7. BZOJ 1123: [POI2008]BLO

    1123: [POI2008]BLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1030  Solved: 440[Submit][Status] ...

  8. BZOJ 1121: [POI2008]激光发射器SZK

    1121: [POI2008]激光发射器SZK Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 792  Solved: 653[Submit][Sta ...

  9. BZOJ1132: [POI2008]Tro

    1132: [POI2008]Tro Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 815  Solved: 211[Submit][Status] ...

  10. BZOJ1116: [POI2008]CLO

    1116: [POI2008]CLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 565  Solved: 303[Submit][Status] ...

随机推荐

  1. 【NX二次开发】Block UI 树列表

    属性说明 属性   类型   描述   常规           BlockID    String    控件ID    Enable    Logical    是否可操作    Group    ...

  2. Windows内核开发-Windows内部概述-2-

    Windows内部概述-2- 线程: 执行代码的实体是线程.一个线程的包含在进程里面的,线程使用进程提供的资源来运行代码. 一个线程拥有以下的内容: 1:明确的运行模式,用户态或者内核态. 2:执行的 ...

  3. winform/WPF 多语言的实现

    WPF实现起来非常现代化,可以参考 https://www.cnblogs.com/yang-fei/p/4854460.html winform主要说一下实现过程和注意点,实现参考AutoUpdat ...

  4. 学习Qt Charts - 不使用UI的情况下使用QTCharts

    新建一个Qt Widgets Application项目,不添加UI文件,如下图: 建立工程后,在.pro文件中添加: QT += charts 然后在.h文件中添加: #include " ...

  5. gRPC(2):四种基本通信模式

    在 gRPC(1):入门及简单使用(go) 中,我们实现了一个简单的 gRPC 应用程序,其中双方通信是简单的请求-响应模式,没发出一个请求都会得到一个响应,然而,借助 gRPC 可以实现不同的通信模 ...

  6. Kubernetes之job

    1.运行单个任务的pod ReplicationController.ReplicaSet.DaemonSet会持续运行任务,永远达不到完成态 .这些 pod 中的进程在退出时会重新启动.但是在一个可 ...

  7. Linux中useradd的用法

    语法:useradd [选项] 用户名 选项: -d<登陆目录> 指定新用户登陆的起始目录,默认为/home -e<有效期限> 指定用户的有效期限,格式为 YYYY-MM-DD ...

  8. gitla 报错 The project you were looking for could not be found or you don't have permission to view it.

    gitlab项目组下创建项目 $ git push -u git@192.168.101.129:/DrvOps/Dev_Test : 报错信息如下: remote: ================ ...

  9. 探索颜色渐变绘制算法(基于Processing语言) 第一部分

    突然间意识到连续变化的颜色在程序中是如何实现的这一问题.没错,就想有事找事,我会分好几部分慢慢探寻,其实笔者也不会,咱一起研究.ok,我们开始! 第一部分 初始部分就从官方案例来入手学习.官方给了三个 ...

  10. 无向图(邻接表实现)DFS_AND_BFS

    数据结构选择TreeSet的原因:通过自定义的Compare方法,保证了点元素的唯一性,有序性(方便检验): 传入Set和Map中的元素类似于C中的指针操作,即共享地址,改变其中一个中的元素,与之相关 ...