gwyh 测试赛 验题人 - 题解 (非std做法)
测试赛 - ljc20020730 解题报告
标签(空格分隔): solution
Task A Tiat's easy question
首先,判断图中是否存在长度为奇数的环等价于判断图是否为二分图。
这个两个事情互为充分必要条件。
只需要染色即可,图可能不连通。
复杂度\(O(n)\)
# include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,M=2e6+10;
struct rec{
int pre,to;
}a[M<<1];
int n,m,tot,head[N],col[N];
void adde(int u,int v)
{
a[++tot].pre=head[u];
a[tot].to=v;
head[u]=tot;
}
void dfs(int u,int c)
{
col[u]=c;
for (int i=head[u];i;i=a[i].pre) {
int v=a[i].to; int sd=(c==1)?2:1;
if (col[v]==col[u]) { puts("N"); exit(0);}
if (!col[v]) dfs(v,sd);
}
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++) {
int u,v; scanf("%d%d",&u,&v);
adde(u,v); adde(v,u);
}
for (int i=1;i<=n;i++) if (!col[i]) dfs(i,1);
puts("Y");
return 0;
}
Task B Nephren's last plan
我们观察到,完全平方数完全是可以取或者不取的,可以统一起来考虑。
不妨设完全平方数的个数为\(ret_1\)个.
而对于其他非完全平方数,我们可以对其进行完全分解。
设\(a_i\)完全分解中某一项为\(p_i ^ {k_i}\) 其中$p_i \in Prime $
若\(k_i \equiv 0 (mod\ 2)\) , 则 该元素对 质数 \(p_i\) 没有意义。
若\(k_i \equiv 1 (mod\ 2)\) , 则 该元素对 质数 \(p_i\) 有意义。
由于最终必须是连乘使得最终答案是完全平方数,这等价于对每个素数有贡献的元素中只能选择偶数个。 对不同素数有贡献的元素之间又存在连带关系。
所以,对于每一个素数都可以对应一个异或方程组,我们可以将其写成矩阵的形式。
定义矩阵\(A_{i,j}\)表示下列方程组的解 \((x_1 , ... , x_n)\)
$A_{1,1} \times x_1 \bigoplus A_{1,2} \times x_2 \bigoplus...\bigoplus A_{1,n} \times x_n = 0 \(
\)A_{2,1} \times x_1 \bigoplus A_{2,2} \times x_2 \bigoplus...\bigoplus A_{2,n} \times x_n = 0 \(
\)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ......\(
\)A_{n,1} \times x_1 \bigoplus A_{n,2} \times x_2 \bigoplus...\bigoplus A_{n,n} \times x_n = 0 $
可以高斯消元求出矩阵的秩 , 然后求出自由元个数\(ret_2\)。
最终的答案$\ ans \ $一定是\(2^{ret_1+ret_2} \equiv ans \ (mod\ 998244353)\)
注意到值相同的不同元素应该算为不同的元。
# include<bits/stdc++.h>
# define int long long
using namespace std;
bool ok[505],is_pr[505];
int n,cnt,ret1,ret2,num;
int a[1005],t[505][505],pr[505],mark[505];
vector<int>p[505];
void EouLaShai(int Lim)
{
memset(is_pr,true,sizeof(is_pr));
is_pr[1]=false;
for (int i=2;i<=Lim;i++) {
if (is_pr[i]) pr[++pr[0]]=i,mark[i]=i;
for (int j=1;j<=pr[0]&&i*pr[j]<=Lim;j++) {
mark[i*pr[j]]=pr[j];
is_pr[i*pr[j]]=false;
if (i%pr[j]==0) break;
}
}
}
void work(int x)
{
++num; bool flag=false;
while (x!=1) {
int y=mark[x],z=0;
while (x%y==0) x/=y,z++;
if (z&1) p[y].push_back(num),flag=true;
}
if (!flag) --num;
}
int gauss()
{
int i,j,k,x,y;
for (i=1,j=1;i<=cnt&&j<=num;j++) {
k=i; while (k<=cnt&&!t[k][j]) ++k;
if (t[k][j]) {
swap(t[i],t[k]);
for (x=i+1;x<=cnt;x++) if (t[x][j])
for (y=i;y<=num;y++) t[x][y]^=t[i][y];
i++;
}
}
return num-i+1;
}
int Pow(int x,int n,int p)
{
int ans=1;
while (n) {
if (n&1) ans=ans*x%p;
x=x*x%p; n>>=1;
}
return ans%p;
}
signed main()
{
EouLaShai(500); scanf("%lld",&n);
for (int i=1;i<=n;i++) {
int t; scanf("%lld",&t);
if (((int)sqrt(t))*((int)sqrt(t))==t) { ret1++; continue;}
a[++a[0]]=t;
}
for (int i=1;i<=a[0];i++) work(a[i]);
for (int i=1;i<=500;i++) if (is_pr[i] && p[i].size()) {
++cnt;
for (int j=0;j<p[i].size();j++) t[cnt][p[i][j]]=1;
}
int ret2=gauss();
printf("%lld\n",Pow(2,ret1+ret2,998244353));
return 0;
}
Task C Tiat and random
首先,黑点=白点的情况对答案没有贡献,可以不用考虑。
设染黑点数目少于白点数目,显然另外一半情况与该情况完全相同。
设染黑点数目是\(i\),为了满足上述限制,\(i \in [0,\lfloor\frac{k}{2} \rfloor ]\)
那么选取的方法是\(\binom{k}{i}\)种,总贡献是\(\binom{k}{i}(k-2i)\)
所以这道题最终答案就是\(\frac{2 \sum\limits _{i=0} ^{\lfloor\frac{k}{2} \rfloor}\binom{k}{i}(k-2i)}{2^k}\)
即 \((2^{-1})^{k-1} \sum\limits _{i=0} ^{\lfloor\frac{k}{2} \rfloor}\binom{k}{i}(k-2i) \ mod \ 2000003\)
由于有\(n\)组询问,这样计算时间复杂度是\(O(nk)\),
我们考虑转化一下这个式子。
我们关心 $\sum\limits _{i=0} ^{\lfloor\frac{k}{2} \rfloor}\binom{k}{i}(k-2i) $ 这一部分。
原式可化为 : \(k \sum\limits_{i=0}^{\lfloor\frac{k}{2} \rfloor}\binom{k}{i} - 2\sum\limits_{i=0}^{\lfloor\frac{k}{2} \rfloor} i\binom{k}{i}\)
显然若\(k = 2k'\)或\(k=2k'+1,k'\in Z\),需要讨论。
观察\(\sum\limits_{i=0}^{\lfloor\frac{k}{2} \rfloor}\binom{k}{i}\) 我们可以归纳得出,
- 当\(k=2k'\)时,值就是$2^{k-1} + \frac{1}{2} \binom{k}{k'} $
- 当\(k=2k'+1\)时,值就是\(2^{k-1}\).
观察\(\sum\limits_{i=0}^{\lfloor\frac{k}{2} \rfloor} i\binom{k}{i} = \sum\limits_{i=1}^{\lfloor\frac{k}{2} \rfloor} i\binom{k}{i}\),而可以证明:$i\binom{k}{i} = k \binom{k-1}{i-1} $
这里证明一下结论 \(i\binom{k}{i} = k \binom{k-1}{i-1}\) : $i\binom{k}{i} =\frac{i\times k!}{(k-i)!i!} = \frac{k\times(k-1)!}{(k-i)!(i-1)!} = k\binom{k-1}{i-1} $
\(\sum\limits_{i=0}^{\lfloor\frac{k}{2} \rfloor} i\binom{k}{i}\)可化为\(k \sum\limits_{i=1}^{\lfloor\frac{k}{2} \rfloor} \binom{k-1}{i-1} = k \sum\limits_{i=0}^{\lfloor\frac{k}{2} \rfloor -1} \binom{k-1}{i}\)
我们可以归纳得出:
- 当\(k=2k'\)时,答案就是\(2^{k-2}k\),
- 当\(k=2k'+1\)时,答案就是\(\frac{2^{k-1}-\binom{k-1}{k'}}{2} k\).
由于真正的答案 $ Ans = (2{-1}){k-1} (k \sum\limits_{i=0}^{\lfloor\frac{k}{2} \rfloor}\binom{k}{i} - 2\sum\limits_{i=0}^{\lfloor\frac{k}{2} \rfloor} i\binom{k}{i})$
- 若当\(k=2k'\)时,
\(Ans = (2^{-1})^{k-1} \times (k(2^{k-1} + \frac{1}{2} \binom{k}{k'})-2(k\times 2^{k-2}))\)
\(= (2^{-1})^k k \binom{k}{k'} = 2k'\binom{2k'}{k'}(2^{-1})^{2k'}\) - 若当\(k=2k'+1\)时,
$Ans = (2{-1}){k-1} \times (k(2^{k-1})-2\times \frac{2^{k-1}-\binom{k-1}{k'}}{2} k ) \(
\)= \binom{k-1}{k'} k (2^{-1}) ^{k-1} =(2k'+1) \binom{2k'-1}{k'} (2^{-1}) ^{2k'-1}$
综上所述,(当\(k\)为奇数且为1时,组合数会取到负数,我们可以特判处理)
\(Ans(1) = \frac{|1-0|+|0-1|}{2^1} = 1.\)
\(Ans(2k') = 2k'\binom{2k'}{k'}(2^{-1})^{2k'} , k' \in N\).
\(Ans(2k'+1) = (2k'+1) \binom{2k'-1}{k'} (2^{-1}) ^{2k'-1},k'\in N^+\).
实现方面,可以预处理逆元、阶乘前缀积、阶乘逆元前缀积、2的逆元幂次等然后通过lucas定理求出组合数取模,然后由于模数不是非常小,所以询问基本上是\(O(1)\)的。
总复杂度: \(O(n)\)
# include<bits/stdc++.h>
# define int long long
using namespace std;
const int N=2e6+1000;
const int mo=2000003;
int s[N],inv[N],Pow[N];
int n,m;
void init(int len)
{
s[0]=inv[0]=inv[1]=1;
for (int i=1;i<=len;i++) s[i]=s[i-1]*i%mo;
for (int i=2;i<=len;i++) inv[i]=(mo-mo/i)%mo*inv[mo%i]%mo;
for (int i=2;i<=len;i++) inv[i]=inv[i-1]*inv[i]%mo;
Pow[0]=1; for (int i=1;i<=len;i++) Pow[i]=Pow[i-1]*inv[2]%mo;
}
int lucas(int n,int m)
{
if (m>n) return 0;
if (n<mo&&m<mo) return s[n]*inv[n-m]%mo*inv[m]%mo;
return lucas(n%mo,m%mo)*lucas(n/mo,m/mo)%mo;
}
signed main(){
init(2e6+100);
int n; scanf("%lld",&n);
while (n--) {
int k; scanf("%lld",&k);
if (k==1) { puts("1");continue;}
if (k&1) {
k/=2; int ans=(2*k+1)*Pow[2*k-1]%mo*lucas(2*k-1,k)%mo;
printf("%lld\n",ans);
} else {
k/=2; int ans=(2*k)*Pow[2*k]%mo*lucas(2*k,k)%mo;
printf("%lld\n",ans);
}
}
return 0;
}
gwyh 测试赛 验题人 - 题解 (非std做法)的更多相关文章
- ACM学习历程—Hihocoder编程之美测试赛B题 大神与三位小伙伴(组合数学 )
时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给你一个m x n (1 <= m, n <= 100)的矩阵A (0<=aij<=10000),要 ...
- 2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告
2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh ...
- 2018.12.7 浪在ACM 集训队第八次测试赛
2018.12.7 浪在ACM 集训队第八次测试赛 https://blog.csdn.net/QLU_minoz/article/details/84886717 感谢苗学林同学C题和D题题解 ...
- HDU100题简要题解(2060~2069)
这十题感觉是100题内相对较为麻烦的,有点搞我心态... HDU2060 Snooker 题目链接 Problem Description background: Philip likes to pl ...
- 2018.12.21 浪在ACM 集训队第十次测试赛
浪在ACM 集训队第十次测试赛 A Diverse Substring B Vasya and Books C Birthday D LCM A 传送门 题解 B 传送门 题解: 这道题,就比较简单 ...
- nowcoder(牛客网)OI测试赛3 解题报告
昨天因为胡搞了一会儿社团的事情,所以错过(逃过)了nowcoder的测试赛..... 以上,听说还是普及组难度qwq,而且还有很多大佬AK(然而我这么蒻肯定还是觉得有点难度的吧qwq) 不过我还是日常 ...
- HDU-5532//2015ACM/ICPC亚洲区长春站-重现赛-F - Almost Sorted Array/,哈哈,水一把区域赛的题~~
F - Almost Sorted Array Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- noi2019模拟测试赛(四十七)
noi2019模拟测试赛(四十七) T1与运算(and) 题意: 给你一个序列\(a_i\),定义\(f_i=a_1\&a_2\&\cdots\&a_i\),求这个序列的所 ...
- ypACM社团年终赛暨实验室选拔赛题解
记得补题,题目两小时半还是挺困难ak的,毕竟我验题也验了几天的时间,题目基本没有锅.题目基本属于简单题 我的三道题都是很基本的题目,希望大家补题 这些题解都是我写的,如果有疑问可以qq问我 所有的核心 ...
随机推荐
- Go语言中 Print,Println 和 Printf 的区别(八)
Print 和 Println 这两个打印方式类似,只在格式上有区别 1. Println 打印的每一项之间都会有空行,Print 没有,例如: fmt.Println("go", ...
- Junit+Mock单元测试
项目用的是maven,所需jar包在pom.xml文件里面配置,单元测试要用的jar具体如下: <dependency> <groupId>junit</groupId& ...
- linux 三剑客之awk总结
AWK 1.begin end使用 cat /tmp/passwd |awk -F ':' 'BEGIN {print "hello"} {print $1"\t&quo ...
- 3的倍数 或运算构造x(牛客第四场)-- triples I
题意: 给你一个数,希望你能用最少的3的倍数或运算成它,让你输出答案. 思路: 进制%3有规律,1.2.4.8.16%3是1.2.1.2.1 ... 利用这一点分情况取一些位合成一些数就是答案了. # ...
- Mysql-Sqlalchemy-ORM框架
import sqlalchemy from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declar ...
- 【Java】Java程序报错:EXCEPTION_ACCESS_VIOLATION (0xc0000005)
运行Java程序的时候,报错:EXCEPTION_ACCESS_VIOLATION (0xc0000005): 根据原网页的说明: EXCEPTION_ACCESS_VIOLATION In rare ...
- tomcat启动报ClassNotFound
排除本来就缺少该类的原因,经过自己经验和网上查的资料,解决方式如下: jar包冲突(关闭其他项目) eclipse的java版本不对,点击项目,右键properties在project facets, ...
- 小程序存emoji表情 不改变数据库
1.小程序:提交前先编码 encodeURIComponent(data) 2.服务端解码(PHP) urldecode(data) 3.如果有空格字符串的,保存之前先对空格进行处理,不然空格在页面会 ...
- Hadoop学习之 HIVE 多用户模式安装
一.启动hadoop 集群 1.启动zookeeper 集群 zkServer.sh start 2.在master.hadoop 机器上 ./start-all.sh 由于 start-all命 ...
- iOS H5页面打开APP技术总结
iOS端H5页面打开APP的方式目前主要有两种:URL Scheme和Universal Links.其中Universal Links是iOS9.0以后推出的一种新的方案,由于它需要在iOS9.0以 ...