很有思维的一道题

这个题的题面非常简单,出题人很友好,没有搞什么奇怪的背景,(卡农(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. 「题解」NWRRC2017 Joker

    本文将同步发布于: 洛谷博客: csdn: 博客园: 简书. 题目 题目链接:洛谷 P7028.gym101612J. 题意概述 有一个长度为 \(n\) 的数列,第 \(i\) 个元素的值为 \(a ...

  2. 汉枫Wi-Fi串口服务器HF2211S应用案例

    实现的功能 该模块上电后主动以mobusRTU协议,通过本模块的串口将气体检测仪的4路传感器数据读取 模块上电后连接指定WiFi,通过MQTT协议将读取到的数据以JSON格式推送到指定服务器. 具体细 ...

  3. Docker与k8s的恩怨情仇(一)—成为PaaS前浪的Cloud Foundry

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 大家在工作中或许或多或少都接触过Docker,那你知道Docker以及容器化背后的原理到底是什么吗? 容器化 ...

  4. RobotFramework常用断言关键字

    变量或者关键字内容判断关键字 1.内容包含或者不包含:should contain . should not contain 与should contain x times *** Test Case ...

  5. 【NX二次开发】调整视图大小

    调整视图大小 tag_t tagView; UF_VIEW_ask_work_view(&tagView); UF_VIEW_fit_view(tagView, 0.7);//if NULL_ ...

  6. Mysql_SQLyog 数据库的创建

    1.创建数据库 CREATE DATABASE [IF NOT EXISTS] westos; 2.删除数据库 DROP DATABASE [IF EXISTS] westos; 3.使用数据库 -- ...

  7. Spring Boot WebFlux-03——WebFlux 整合 MongoDB

    第03课:WebFlux 整合 MongoDB 前言 上一课的内容讲解了用 Map 数据结构内存式存储了数据,这样数据就不会持久化,本文我们用 MongoDB 来实现 WebFlux 对数据源的操作. ...

  8. SpringBoot和Spring到底有没有本质的不同?

    现在的Spring相关开发都是基于SpringBoot的.最后在打包时可以把所有依赖的jar包都打进去,构成一个独立的可执行的jar包.如下图: 使用java -jar命令就可以运行这个独立的jar包 ...

  9. 与KubernetesAPI服务器交互

    在介绍过的Downward API提供了一种简单的方式,将pod和容器的元数据传递给在它们内部运行的进程.但这种方式其实仅仅可以暴露一个pod自身的元数据,而且只可以暴露部分元数据.某些情况下,应用需 ...

  10. centos8 安装VNC配置远程连接

    系统信息 [root@centos8 ~]# cat /etc/redhat-release CentOS Linux release 8.1.1911 (Core) [root@centos8 ~] ...