补题进度:9/10

A(多项式)

题意:

  在一个长度为n=262144的环上,一个人站在0点上,每一秒钟有$\frac{1}{2}$的概率待在原地不动,有$\frac{1}{4}$的概率向前走一步,有$\frac{1}{4}$概率向后走一步,问t秒后这个人在x点的概率是多少,结果模998244353

分析:

  我们设:

    留在原地:$1$

    前进一步:$x$

    后退一步:$x^{-1}$

  那么最后实际上是要求n=262144意义下$(\frac{x^{-1}}{4}+\frac{1}{2}+\frac{x}{4})^t$的第x项的系数

  因为n是p-1的因数,所以可以选n个单位根快速幂求值,然后NTT插值插出多项式即可。

  时间复杂度O(nlogn)

B(JAVA/模大质数)

C(LIS)

D(行列式+容斥)

题意:

  给出一个长度为n的数组a,其中$a_i<a_{i+1}$

  有n个机器人,第i个机器人在平面上的$(-a_i,a_i)$位置,每一秒钟可以向上走一步或者向右走一步

  有n个终点,第i个终点在平面上的$(a_{n+i-i},m-a_{n+i-i})$位置,其中m是给定常数

  在同一秒中同一个位置不能有两个机器人

  现在每个机器人都要到它对应的终点去,问有多少合法的不冲突的走路方案,答案模p

  1<=n<=100,1<=m<=1e18,2<=p<=1e9+7,0<=$a_i$<=1000

分析:

   我们发现两个机器人在同一秒在同一个位置这与它们的路径相交是等价的,于是问题就变成了求路径互相不相交的方案数

  这个就利用16年多校的一个用行列式来容斥的题的套路差不多了,具体就是$a_{i,j}$表示第i个机器人走到第j个终点的方案数,然后求$det a$的值就是最后的结果了

  这里注意到每个机器人走的步数一定都是m,那么第i个机器人走到第j个终点的方案数就是C(m,a[i]+a[n-j+1])

  于是我们要想办法快速求出C(m,0),C(m,1),....,C(m,2000)

  有一个$O(2000^2 * log(m))$的倍增方法来计算它

  具体就是C(2m,i)=C(m,0)*C(m,i)+C(m,1)*C(m,i-1)+...+C(m,i)*C(m,0),即要从2m个数中挑i个,我可以将2m个数分成左右两部分,左右两部分各自挑,总和是i就行了

  然后因为是模非质数,所以求行列式就不能直接求逆了,可以用辗转相减法求行列式

 #include<bits/stdc++.h>
using namespace std;
const int maxn=;
int c[maxn+],x[maxn+];
int a[maxn+][maxn+];
int n,mod;
long long m,ans;
void cal(long long m)
{
if(m==)
{
c[]=;
return;
}
if(m&)
{
cal(m-);
for(int i=maxn;i>;--i) c[i]=(c[i]+c[i-])%mod;
}
else
{
cal(m/);
for(int i=maxn;i>;--i)
for(int j=;j<i;++j)
c[i]=(c[i]+1LL*c[j]*c[i-j])%mod;
}
}
int main()
{
scanf("%d%lld%d",&n,&m,&mod);
cal(m);
for(int i=;i<=n;++i) scanf("%d",&x[i]);
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
a[i][j]=c[x[i]+x[n-j+]];
ans=;
cout<<clock()<<endl;
for(int i=;i<=n;++i)
for(int j=i+;j<=n;++j)
while(a[j][i])
{
int d=a[i][i]/a[j][i];
for(int k=;k<=n;++k)
{
a[i][k]=(a[i][k]-1LL*d*a[j][k]%mod+mod)%mod;
swap(a[i][k],a[j][k]);
}
ans=-ans;
}
ans=(ans+mod)%mod;
for(int i=;i<=n;++i) ans=ans*a[i][i]%mod;
printf("%lld\n",ans);
return ;
}

E(线段树)

题意:

  有一个长度为n的数组a,要支持两个操作:

  0 l r x :在[l,r]中的$\frac{(r-l+1)(r-l+2)}{2}$个子区间中等概率随机选一个,给其中的所有数加上x

  1 l r    :在[l,r]中的$\frac{(r-l+1)(r-l+2)}{2}$个子区间中等概率随机选一个,问这个子区间的和的期望是多少

  答案对998244353求模

  1<=n<=100000,1<=m<=100000

分析:

  可以推一波式子,发现加操作相当于给一段区间加上一个二次函数$ax^2+bx+c$,询问相当于问一段区间每个位置乘上一个二次函数之后的和

  我们可以用线段树维护一段区间[l,r]的Σa[i]、Σi*a[i]、Σi^2a[i]就能把每个询问拆成三部分然后累加求和了

  对于修改我们打lazy就行了

F(AC自动机+容斥+矩乘)

题意:

  给出n个字符串,问长度为l的字符串有多少个是包含了这n个字符串作为子串的。

  0<=l<=1e9,1<=n<=8,每个串长度不超过6

分析:

  如果l比较小,那就建个AC自动机,然后在上面跑状压DP就行了,dp[i][j][s]表示跑了i步在AC自动机的j点,字符串包含情况是S的情况下的方案数

  但现在问题是l很大,考虑把第一维用矩阵乘法代替

  那么很容易想到建一个k=48*256的转移矩阵,然后矩阵快速幂

  这是可以在O(klogk logl)的时间内完成的(用FFT优化O(k^2logl)的算法),但不是很好写而且常数巨大

  这题n比较小可以考虑把这些字符串容斥,我们每次求出“至少不经过这样几个串的方案数”,就是1<<n次k=48的矩阵乘法,用O(k^3logl)的算法即可

G(FWT)

题意:

  FWT

分析:

  FWT真板子题

H(递推数列循环节)

待填坑

I(图论构造)

J(polya计数)

题意:

  你需要给n*m矩阵的每个格子填上0/1

  矩阵循环平移之后如果相同则视为相同

  矩阵每一行的异或和、每一列的异或和必须是0

  你需要求出有多少种本质不同的染色方案

  n,m<=1e9

分析:

  明显的二维polya计数,如果没有“同行同列异或和为0”这一限制,那答案明显就是

  其中a和b分别是行/列的循环节长度,即n/a,m/b分别是行、列的平移量,我们来讨论该种置换下不动点的个数

  原本自由变元的数目是nm/lcm(a,b),现在有了“同行同列异或和为0”这一限制,我们需要牺牲一些自由变元

  我们首先来考虑行限制,行限制应该是类似下面这种的:

  1 xor 2 xor 3 xor 1 xor 2 xor 3 xor 1 xor 2 xor 3 ...... =0

  4 xor 5 xor 6 xor 4 xor 5 xor 6 xor 4 xor 5 xor 6 .......=0

  .....

  那么本质不同的行限制方程明显有n/a个,即行循环的步长,那么这n/a个方程是不是都有效呢?

  我们还要考虑同一行中所有数字的重复次数,如果是奇数,那么这个方程是有效的,如果是偶数,那么是恒等于0的,是无效的

  那么循环次数是多少呢?

  一个数字再矩阵中一共出现l次,在同一列出现了a次,所以一共会在l/a列出现,即同一行每个数字会出现l/a次,我们只需要判断l/a的奇偶性就可以了

  对于列限制我们同理去考虑

  然后拿刚开始的自由元去减去有效方程的个数,就是真正自由元的数目

  注意,如果l/a l/b都是奇数,那么这两组方程会导出一个无效方程(就是把所有的行限制异或起来和把所有列限制异或起来会得到矩阵的整体异或方程),所以自由元需要减去1

  注意实现精妙一些就行,我们可以先把n,m质因数分解,然后dfs去构造他们的因数,因为这样比较方便在构造过程中求出每个的欧拉函数

 #include<bits/stdc++.h>
using namespace std;
#define mp make_pair
const int mod=1e9+;
vector<pair<int,int> > A,B,a,b;
int n,m;
void prime(vector<pair<int,int> > &a,int x)
{
int limit=sqrt(x+0.5);
for(int i=;i<=limit;++i)
if(x%i==)
{
int s=;
while(x%i==) x/=i,++s;
a.push_back(mp(i,s));
}
if(x!=) a.push_back(mp(x,));
}
void dfs(vector<pair<int,int> > &A,vector<pair<int,int> > a,int k,int factor,int fai)
{
if(k==a.size()) A.push_back(mp(factor,fai));
else
{
for(int i=;i<=a[k].second;++i)
{
dfs(A,a,k+,factor,fai);
factor=factor*a[k].first;
if(i==) fai=fai*(a[k].first-);else fai=fai*a[k].first;
}
}
}
long long Pow(long long a,long long b)
{
long long ans=;
while(b)
{
if(b&) ans=ans*a%mod;
a=a*a%mod;
b>>=;
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
a.clear(),b.clear(),A.clear(),B.clear();
prime(a,n);
prime(b,m);
dfs(A,a,,,);
dfs(B,b,,,);
long long sum=;
for(int i=;i<A.size();++i)
for(int j=;j<B.size();++j)
{
long long ans=;
ans=ans*A[i].second%mod*B[j].second%mod;
long long lcm=1LL*A[i].first/__gcd(A[i].first,B[j].first)*B[j].first;
long long num=1LL*n*m/lcm;
if(lcm/A[i].first%==&&lcm/B[j].first%==) num-=n/A[i].first+m/B[j].first-;
else
if(lcm/A[i].first%==) num-=n/A[i].first;
else
if(lcm/B[j].first%==) num-=m/B[j].first;
ans=ans*Pow(2LL,num)%mod;
sum=(sum+ans)%mod;
}
printf("%lld\n",sum*Pow(1LL*n,1LL*mod-)%mod*Pow(1LL*m,1LL*mod-)%mod);
}
return ;
}

寒武纪camp Day3的更多相关文章

  1. 寒武纪camp网络测试赛

    寒武纪camp网络测试赛 地址:oj点我进入 A(树形dp+树链剖分) 题意: 分析: 考虑树形dp,f0(x)和f1(x)分别表示以x为根的子树,不取x点或取x点的最大合法子集的元素个数 那么对于一 ...

  2. CCPC-Wannafly Winter Camp Day3 Div1 - 精简改良 - [生成树][状压DP]

    题目链接:https://zhixincode.com/contest/14/problem/D?problem_id=206 样例输入 1  5 5 1 2 1 1 3 1 2 4 1 2 5 1 ...

  3. CCPC-Wannafly Winter Camp Day3 Div1 - 石头剪刀布 - [带权并查集]

    题目链接:https://zhixincode.com/contest/14/problem/I?problem_id=211 样例输入 1  3 5 2 1 1 2 1 2 1 1 2 3 2 1 ...

  4. CCPC-Wannafly Winter Camp Day3 Div1 - 排列

    题目链接:https://zhixincode.com/contest/14/problem/A?problem_id=203 time limit per test: 1 secondmemory ...

  5. CCPC-Wannafly Winter Camp Day3 (Div2, onsite)

    Replay Dup4: 没想清楚就动手写? 写了两百行发现没用?想的还是不够仔细啊. 要有莽一莽的精神 X: 感觉今天没啥输出啊, 就推了个公式?抄了个板子, 然后就一直自闭A. 语文差,题目没理解 ...

  6. 2019 CCPC-Wannafly Winter Camp Day3(Div2, onsite)

    solve 4/11 补题:5/11 A 二十四点* Code:pai爷  zz Thinking :pai爷 打表找规律,1张牌 10个不可能的 2张牌有 43 种不可能的 3张牌 有74 种不可能 ...

  7. 石头剪刀布(2019Wannafly winter camp day3 i) 带权并查集+按秩合并 好题

    题目传送门 思路: 按照题意描述,所有y挑战x的关系最后会形成一棵树的结构,n个人的总方案数是 3n 种,假设一个人被挑战(主场作战)a次,挑战别人(客场)b次,那么这个人存活到最后的方案数就是3n* ...

  8. 【CCPC-Wannafly Winter Camp Day3 (Div1) G】排列(水题)

    点此看题面 大致题意:已知 \(p\)为\(n\)的一个排列,定义\(A(p)_i=min_{j=1}^ip_j\),若用\(q_i\)表示\(p\)第\(i\)小的前缀的长度(以值为第一关键字,下标 ...

  9. 【CCPC-Wannafly Winter Camp Day3 (Div1) F】小清新数论(莫比乌斯反演+杜教筛)

    点此看题面 大致题意: 让你求出\(\sum_{i=1}^n\sum_{j=1}^n\mu(gcd(i,j))\). 莫比乌斯反演 这种题目,一看就是莫比乌斯反演啊!(连莫比乌斯函数都有) 关于莫比乌 ...

随机推荐

  1. sqlserver2012 offset

    /* * Hibernate, Relational Persistence for Idiomatic Java * * License: GNU Lesser General Public Lic ...

  2. Linux下搭建DHCP服务器

    一.DHCP所需软件包 dhcp-common-4.1.1-34.Pl.el6.centos.x86_64 dhcp-4.1.1-34.pl.el6.centon.x86_64 二.编辑主配置文件 v ...

  3. 自定义Jquery分页插件

    /** * 功能说明:jPager 分页插件 * 参数说明:pages:[] 分页的控件个数 @id:显示分页的div ID,@showSelectPage: 是否显示当前分页的条目过滤下拉框 * @ ...

  4. MongoDB最简单的入门教程之二 使用nodejs访问MongoDB

    在前一篇教程 MongoDB最简单的入门教程之一 环境搭建 里,我们已经完成了MongoDB的环境搭建. 在localhost:27017的服务器上,在数据库admin下面创建了一个名为person的 ...

  5. MySql数据库--持续记录ing

    1 基本,引擎,数据类型,运算1.1 基本操作启动:net start mysql停止:net stop mysql连接: mysql –uroot -h127.0.0.1 -proot断开连接:qu ...

  6. .NET多线程总结

    1.不需要传递参数,也不需要返回参数 我们知道启动一个线程最直观的办法是使用Thread类,具体步骤如下: public void test() { ThreadStart threadStart = ...

  7. Bug的分类和管理流程

    1.按照严重程度划分 定义:是指Bug对软件质量的破坏程度,即BUG的存在将对软件的功能和性能产生怎样的影响 分类:系统崩溃.严重.一般.次要.建议 2.按优先级划分 定义:表示处理和修正软件缺陷的现 ...

  8. js 数组元素排序?

    Part.1  sort 方法 js 有自带排序方法 sort(),  默认 升序 排列 如: data() { return { arr: [1,3,2,5,6,8,7,4,9] } }, 控制台如 ...

  9. 最短路 || HDU 2066 一个人的旅行

    本草的旅行故事(✺ω✺),可以从S个点中的任意一个开始,到达D个点中的任意一个,求最短路 *解法:把草儿的家记成点0,S个点与0的距离为0,然后spfa求最短路 又是改了一万次,①多组数据啊 ②改完多 ...

  10. HTML基础(三)图像和超链接

    图像 img 元素向网页中嵌入一幅图像. 语法 <img src="" alt="" /> img标签常用属性 src 跳转的url alt 图片不 ...