A.Matrix

挺狗的一道题,从开始冲到最后都没冲出来,都没啥思路。

其实分开考虑每个数的贡献,这个想法也存在过,就是不知道该怎么计算,我们考虑我们单独考虑一个数字\(i(1\leq i\leq n)\)的贡献,其实就是在有一行答案是\(i\)的情况下总的方案数有多少个。同时我们注意到,每个不同的数之间是互不冲突的,因为在一个方案中,我们也是每行求每个数的答案然后累加起来。所以我们只考虑一个数在多少个不同的方案里贡献了答案。首先我们要选一行,其次保证这一行的答案是\(i\),考虑到这一行的其他数必须都比它大,也就是\(C_{n^2-i}^{n-1}\)个,其次考虑这一行\(n\)个数的排列,就是\(n!\),还有就是除了这一行,其他所有数的排列。就是\((n^2-n)!\)也就是说单独一个\(i\)的贡献就是\(n*C_{n^2-i}^{n-1}*n!*(n^2-n)!\)所有数的答案就是\(ans=n*n!*(n^2-n)!\sum_{i=1}^{n}C_{n^2-i}^{n-1}\)数据\(n=5000\),随便都可以过。

//不等,不问,不犹豫,不回头.
#include<bits/stdc++.h>
#define _ 0
#define ls p<<1
#define db double
#define rs p<<1|1
#define P 998244353
#define ll long long
#define INF 1000000000
#define get(x) x=read()
#define PLI pair<ll,int>
#define PII pair<int,int>
#define ull unsigned long long
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(x,y,z) for(int x=y;x<=z;++x)
#define fep(x,y,z) for(int x=y;x>=z;--x)
#define go(x) for(int i=link[x],y=a[i].y;i;y=a[i=a[i].next].y)
using namespace std;
const int N=5005;
ll jc[N*N]; inline int read()
{
int x=0,ff=1;
char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*ff;
} inline ll power(ll x,int y)
{
ll ans=1;
while(y)
{
if(y&1) ans=ans*x%P;
y>>=1;
x=x*x%P;
}
return ans%P;
} inline void prework()
{
jc[0]=1;
rep(i,1,25000000) jc[i]=jc[i-1]*i%P;
} inline ll C(int n,int m) {return jc[n]*power(jc[m],P-2)%P*power(jc[n-m],P-2)%P;} int main()
{
//freopen("1.in","r",stdin);
prework();
int get(T);
while(T--)
{
int get(n);
ll ans=n;
ans=ans*jc[n]%P*jc[n*n-n]%P;
ll p=0;
rep(i,1,n) p=(p+C(n*n-i,n-1))%P;
putl(ans*p%P);
}
return (0^_^0);
}
//以吾之血,铸吾最后的亡魂.

B.Cypher

关于机关解密的大模拟题....看懂题意谁都会做....

//不等,不问,不犹豫,不回头.
#include<bits/stdc++.h>
#define _ 0
#define ls p<<1
#define db double
#define rs p<<1|1
#define P 1000000007
#define ll long long
#define INF 1000000000
#define get(x) x=read()
#define PLI pair<ll,int>
#define PII pair<int,int>
#define ull unsigned long long
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(x,y,z) for(int x=y;x<=z;++x)
#define fep(x,y,z) for(int x=y;x>=z;--x)
#define go(x) for(int i=link[x],y=a[i].y;i;y=a[i=a[i].next].y)
using namespace std;
const int N=60;
int p,n,cnt[N],Q;
char id[N],pan[N][3][N],c[N],fan[N],sr[N]; inline int read()
{
int x=0,ff=1;
char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*ff;
} inline void roll(int id)
{
char c=pan[id][1][0];
rep(i,0,24) pan[id][1][i]=pan[id][1][i+1];
pan[id][1][25]=c;
c=pan[id][2][0];
rep(i,0,24) pan[id][2][i]=pan[id][2][i+1];
pan[id][2][25]=c;
} inline char solve(char o)
{
int now=1;
while(1)
{
roll(now);
cnt[now]++;
if(cnt[now]%26!=0) break;
now++;
}
int Id=(int)id[o-'A']-'A';
rep(i,1,n)
{
char c=pan[i][1][Id];
rep(j,0,25) if(pan[i][2][j]==c) {Id=j;break;}
}
rep(i,0,25) if(fan[i]-'A'==Id) {Id=i;break;}
fep(i,n,1)
{
char c=pan[i][2][Id];
rep(j,0,25) if(pan[i][1][j]==c) {Id=j;break;}
}
return id[Id];
} int main()
{
//freopen("1.in","r",stdin);
int get(T);
while(T--)
{
get(p);
rep(i,0,25) id[i]='A'+i;
rep(i,1,p)
{
scanf("%s",sr+1);
swap(id[sr[1]-'A'],id[sr[2]-'A']);
}
get(n);
rep(i,1,n)
{
rep(j,0,25) pan[i][1][j]='A'+j;
}
rep(i,1,n) scanf("%s",pan[i][2]);
memset(cnt,0,sizeof(cnt));
rep(i,1,n)
{
int get(x);
cnt[i]+=x;
rep(j,1,cnt[i])
{
roll(i);
if(cnt[i]%26==0&&i!=n) roll(i+1),cnt[i+1]++;
}
}
scanf("%s",fan);
get(Q);
rep(i,1,Q)
{
scanf("%s",sr+1);
int m=strlen(sr+1);
rep(j,1,m) printf("%c",solve(sr[j]));
puts("");
}
}
return (0^_^0);
}
//以吾之血,铸吾最后的亡魂.

C.Vertex Deletion

关于删点的问题,关于这个题,当时也想到了可能要用到树形\(dp\)去解决,也想到了要设\(f[x][0/1]\)来表示清楚当前这个点删不删的方案数,可还是想不太清楚,就弃了。

首先第一个是设状态的问题,我们先考虑我们随便切之后可能会有哪些状态,从根节点往下看,以当前点\(x\)为例,无外乎就三种状态:\(x\)被删掉,\(x\)被保留且只有\(x\)单独的一个点(即\(x\)不与其他点相连),\(x\)被保留且至少还连着其他的一个点。既然有三种状态,那我们设状态时就可以先这样设着\(f[x][0/1/2]\),没有用的时候再剔除也行。那么考虑\(dfs\)的时候,状态如何转移,注意我们定义的状态是以当前点\(x\)为根的子树中,\(x\)处于以上状态时的合法方案数。

那么当\(x\)被删除时,其各个儿子被相互独立那么儿子只能选择连着其儿子来保持方案合法或者选择删除自己。则\(f[x][0]=\prod (f[y][2]+f[y][0])\)。

当\(x\)被保留且单独一个点时,那么儿子必须全部删去,否则就会使得\(x\)与\(y\)相连。即\(f[x][1]=\prod f[y][0]\)

当\(x\)被保留且至少连一个点时,这个方案有点多,我们只要和任意一个儿子相连即可。如果正着求不太行的话,我们考虑容斥,每个儿子有两种选择,要么保留,要么删除,而其中保留还可以选择至少连一个点和删除,这样的话我们直接将所有儿子的两种选择都选上即\(f[x][1]=\prod (f[y][1]+f[y][0]+f[y][2])\)可这样的话发现当所有儿子选择删除时,我们当前的状态就不合法了,但只有这一种情况下才不合法我们直接从总方案中减去即可,而发现这种方案恰好就是\(f[x][1]\)。即\(f[x][1]=\prod (f[y][1]+f[y][0]+f[y][2])-f[x][1]\)。那么最后的答案就是\(f[1][0]+f[1][2]\).

//不等,不问,不犹豫,不回头.
#include<bits/stdc++.h>
#define _ 0
#define ls p<<1
#define db double
#define rs p<<1|1
#define P 998244353
#define ll long long
#define INF 1000000000
#define get(x) x=read()
#define PLI pair<ll,int>
#define PII pair<int,int>
#define ull unsigned long long
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(x,y,z) for(int x=y;x<=z;++x)
#define fep(x,y,z) for(int x=y;x>=z;--x)
#define go(x) for(int i=link[x],y=a[i].y;i;y=a[i=a[i].next].y)
using namespace std;
const int N=1e5+10;
ll f[N][3],n;
vector<int>son[N]; inline int read()
{
int x=0,ff=1;
char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*ff;
} inline void dfs(int x,int fa)
{
f[x][0]=f[x][1]=f[x][2]=1;
for(auto y:son[x])
{
if(y==fa) continue;
dfs(y,x);
f[x][0]=(f[x][0]*(f[y][2]+f[y][0]))%P;
f[x][1]=(f[x][1]*f[y][0])%P;
f[x][2]=(f[x][2]*(f[y][0]+f[y][1]+f[y][2]))%P;
}
f[x][2]=(f[x][2]-f[x][1]+P)%P;
} int main()
{
//freopen("1.in","r",stdin);
int get(T);
while(T--)
{
get(n);
rep(i,1,n) son[i].clear();
rep(i,1,n-1)
{
int get(x),get(y);
son[x].push_back(y);
son[y].push_back(x);
}
dfs(1,0);
putl((f[1][0]+f[1][2])%P);
}
return (0^_^0);
}
//以吾之血,铸吾最后的亡魂.

D.Lowbit

这个题还是挺好的,发现包括上一次的相乘,这一类题都有一个比较重要的性质,就是某些操作在操作一定次数之后就会出现一些神奇的变化或者不可能成为答案。这个题就是一样的,你会发现这个题每个数在进行一定次数的增加\(lowbit\)之后,等到这个数二进制下只剩一个\(1\)的时候,再加\(lowbit\)就变成乘\(2\)了,而乘\(2\)这个操作我们很容易维护,所以直接写一个线段树,维护一下每个数是不是到达这个状态了即可。

021中国大学生程序设计竞赛(CCPC)- 压力测试赛题解的更多相关文章

  1. HDU6237-A Simple Stone Game-找素因子(欧拉函数)-2017中国大学生程序设计竞赛-哈尔滨站-重现赛

    A Simple Stone Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Ot ...

  2. HDU6235-Permutation-水题-2017中国大学生程序设计竞赛-哈尔滨站-重现赛

    Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Tot ...

  3. HDU 6237.A Simple Stone Game-欧拉函数找素因子 (2017中国大学生程序设计竞赛-哈尔滨站-重现赛)

    A Simple Stone Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Ot ...

  4. HDU 6235.Permutation (2017中国大学生程序设计竞赛-哈尔滨站-重现赛)

    Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Tot ...

  5. HDU 6273.Master of GCD-差分数组 (2017中国大学生程序设计竞赛-杭州站-重现赛(感谢浙江理工))

    Super-palindrome 题面地址:http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf 这道题是差分数组的题目,线 ...

  6. [BFS,A*,k短路径] 2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛 path (Problem - 6705)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=6705 path Time Limit: 2000/2000 MS (Java/Others)    Mem ...

  7. [贪心,dp] 2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛 Fishing Master (Problem - 6709)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=6709 Fishing Master Time Limit: 2000/1000 MS (Java/Othe ...

  8. 2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛(8/11)

    $$2019中国大学生程序设计竞赛(CCPC)\ -\ 网络选拔赛$$ \(A.\hat{} \& \hat{}\) 签到,只把AB都有的位给异或掉 //#pragma comment(lin ...

  9. 2016中国大学生程序设计竞赛 - 网络选拔赛 C. Magic boy Bi Luo with his excited tree

    Magic boy Bi Luo with his excited tree Problem Description Bi Luo is a magic boy, he also has a migi ...

随机推荐

  1. JavaScrip中 Array.reduce()

    数组的方法 reduce() reduce方法在数组的每一项元素上都会执行回调函数. 语法:array.reduce( callBack [ , init]  ) // 语法arrary.reduce ...

  2. 迷宫3---BFS

    经过思考蒜头君终于解决了怎么计算一个迷宫的最短路问题,于是蒜头君找到一个新的迷宫图,来验证自己是否真的会计算一个迷宫的最短路. 为了检验自己计算的是否正确,蒜头君特邀你一起来计算. 输入格式 第一行输 ...

  3. Shell系列(22)- 字符截取命令awk

    简介 awk是一个数据处理工具,相比于sed常常作用于一整行的处理,awk则比较倾向于将一行分成数个"字段"来处理 awk的流程是依次读取每一行数据,读取完一行数据后,进行条件判断 ...

  4. 集群环境下的Session管理

    1. 集群环境下的管理HTTPSSession所遇到的问题 一台服务器对应这个一个session对象,无法在另外一个服务器互通 解决方法: 1. Session 的 Replication(复制)将当 ...

  5. django 常用教程网址

    第一:url中反向解析教程网址 https://docs.djangoproject.com/zh-hans/2.2/ref/templates/builtins/#url

  6. Redis-Cluster分片扩容

    redis分片分片场景在业务量相对较小的时候,可以将所有数据都存到一台机器上,只使用redis单机模式,不存在分片问题.如果业务的数据量超过一台物理机器的内存大小时,则会面对扩展问题,需要多台机器去存 ...

  7. [源码解析] PyTorch 流水线并行实现 (3)--切分数据和运行时系统

    [源码解析] PyTorch 流水线并行实现 (3)--切分数据和运行时系统 目录 [源码解析] PyTorch 流水线并行实现 (3)--切分数据和运行时系统 0x00 摘要 0x01 分割小批次 ...

  8. Kafka分区策略

    Kafka分区策略 所谓分区策略是决定生产者将消息发送到哪个分区的算法.Kafka 为我们提供了默认的分区策略,同时它也支持你自定义分区策略. 常见的分区策略包含以下几种:轮询策略.随机策略 .按消息 ...

  9. P5137-polynomial【倍增】

    正题 题目链接:https://www.luogu.com.cn/problem/P5137 题目大意 \(T\)组数据给出\(n,a,b,p\)求 \[\left(\sum_{0=1}^na^ib^ ...

  10. JuiceFS v0.17 发布,通过 1270 项 LTP 测试!

    小伙伴们大家好,JuiceFS v0.17 在国庆小长假来临之际如期发布了!这是我们在 2021 年秋季推出的第二个版本,让我们直奔主题,看看都有哪些新变化吧. 本次更新累计 80+ 提交,共有 9 ...