预处理

考虑模数\(10\)是合数不好做,所以我们可以用一个常用套路:

\(\prod_{i=l}^ra_i\equiv x(mod\ 10)\)的方案数等于\(\prod_{i=l}^ra_i\equiv x(mod\ 2)\)的方案数乘上\(\prod_{i=l}^ra_i\equiv x(mod\ 5)\)的方案数。

状态设置

考虑接下来怎么求。

既然现在模数是质数,而在模质数意义下的逆元是唯一的,除了\(0\)没有逆元,因此只要特殊考虑\(0\)。

设\(f_{i,j}\)表示 将区间\([i,j]\)填满且满足此区间内所有条件并不能填\(0\)的方案数,\(g_{i,j}\)表示 将区间\([i,j]\)填满且满足此区间内所有条件但可以填\(0\)的方案数

那么答案就是\(g_{1,n}\)。

如何求\(g_{l,r}\)

首先,\(g_{l,r}\)可以从\(f_{l,r}\)转移得到。

然后,考虑枚举一个\(p\),表示\([l,r]\)中最左边的\(0\)的位置。

显然\(p\)要满足条件中不存在一个包含\(p\)的区间积不为\(0\)。

则\(g_{l,r}\)就可以加上\(f_{l,p-1}\times g_{p+1,r}\)。

因为\(p\)是第一个\(0\),所以左边不能有\(0\),右边可以有\(0\)。

如何求\(f_{l,r}\)

因为不能有\(0\),所以我们可以设\(s_i\)表示\(\prod_{x=l}^ia_x\),即前缀积。

对于一组条件例如\([x,y]\)区间内的积为\(v\),则可以得到\(a_{x-1}^{-1}\times a_y=v\)。

我们可以用带权并查集存储这种关系,同时检验是否合法。

当所有条件处理完后,假设有\(t\)个连通块,当前的模数是\(V\),由于不能填\(0\),所以方案数是\((V-1)^{t-1}\)。

即\(f_{l,r}=(V-1)^{t-1}\)。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100
#define Q 50
#define X 1000000007
using namespace std;
int n,Qt;
struct Query
{
int l,r,v;I Query(CI x=0,CI y=0,CI p=0):l(x),r(y),v(p){}
I Query operator % (CI x) Con {return Query(l,r,v%x);}
}s[Q+5];
class DpSolver
{
private:
#define VQ vector<Query>
#define IT VQ::iterator
#define pb push_back
int V,Inv[5],f[N+5][N+5],g[N+5][N+5],fa[N+5],vl[N+5];VQ p;
I int Qpow(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}//快速幂
I int getfa(CI x)//找祖先,路径压缩同时更新边权
{
if(fa[x]==x) return x;RI t=fa[x];fa[x]=getfa(fa[x]),vl[x]=vl[x]*vl[t]%V;
return fa[x];
}
I bool Union(CI x,CI y,CI v)//合并,若已连通判断是否合法
{
RI fx=getfa(x),fy=getfa(y);if(fx==fy) return vl[y]*Inv[vl[x]]%V==v;//判断是否合法
return fa[fx]=fy,vl[fx]=vl[y]*Inv[vl[x]]%V*Inv[v]%V,true;//合并
}
I int F(CI l,CI r,VQ v)//求f[l][r],v表示[l,r]内的条件
{
if(v.empty()) return Qpow(V-1,r-l+1);if(~f[l][r]) return f[l][r];//若无条件随便填,若已求过直接返回
RI i,t=0;IT it;for(i=l-1;i<=r;++i) fa[i]=i,vl[i]=1;//并查集初始化
for(it=v.begin();it!=v.end();++it)//迭代器遍历vector
if(!it->v||!Union(it->l-1,it->r,it->v)) return f[l][r]=0;//若不合法返回0
for(i=l-1;i<=r;++i) i==fa[i]&&++t;return f[l][r]=Qpow(V-1,t-1);//统计连通块个数计算答案
}
I int G(CI l,CI r,VQ v)//求g[l][r],v表示[l,r]内的条件
{
if(v.empty()) return Qpow(V,r-l+1);if(~g[l][r]) return g[l][r];//若无条件随便填,若已求过直接返回
RI i,fg;VQ v1,v2;IT it;for(g[l][r]=F(l,r,v),i=l;i<=r;++i)//枚举第一个0所在位置
{
for(fg=1,v1.clear(),v2.clear(),it=v.begin();it!=v.end();++it)//迭代器遍历vector
{
if(it->l<=i&&i<=it->r&&it->v) {fg=0;break;}//如果一个包含当前位置的区间积不为0,就不合法
it->r<i&&(v1.pb(*it),0),it->l>i&&(v2.pb(*it),0);//将条件分成两部分
}fg&&(g[l][r]=(1LL*F(l,i-1,v1)*G(i+1,r,v2)+g[l][r])%X);//更新g值
}return g[l][r];//返回答案
}
public:
I void Solve()
{
#define Init(x) (V=x,p.clear(),memset(f,-1,sizeof(f)),memset(g,-1,sizeof(g)))
RI i,t;for(Init(2),Inv[1]=1,i=1;i<=Qt;++i) p.pb(s[i]%2);t=G(1,n,p);//模数为2
for(Init(5),Inv[1]=1,Inv[2]=3,Inv[3]=2,Inv[4]=4,i=1;i<=Qt;++i) p.pb(s[i]%5);//模数为5
printf("%d",1LL*t*G(1,n,p)%X);//方案数相乘
}
}S;
int main()
{
freopen("unknown.in","r",stdin),freopen("unknown.out","w",stdout);
RI i;for(scanf("%d%d",&n,&Qt),i=1;i<=Qt;++i)
scanf("%d%d%d",&s[i].l,&s[i].r,&s[i].v),++s[i].l,++s[i].r;//读入,出于习惯将下标加1
return S.Solve(),0;
}

【2019.10.7 CCF-CSP-2019模拟赛 T3】未知的数组(unknown)(并查集+动态规划)的更多相关文章

  1. 2019/8/27 Test(luogu 五月天模拟赛)

    \(2019/8/27\)大考 \(\color{#ff0808}{\text{初二诀别赛(SAD)}}\) 题目名称 链接 寿司 \(BSOJ5111\) 秀秀的森林 \(BSOJ5125\) 分组 ...

  2. 体育成绩统计——20180801模拟赛T3

    体育成绩统计 / Score 题目描述 正所谓“无体育,不清华”.为了更好地督促同学们进行体育锻炼,更加科学地对同学们进行评价,五道口体校的老师们在体育成绩的考核上可谓是煞费苦心.然而每到学期期末时, ...

  3. 20180520模拟赛T3——chess

    [问题描述] 小美很喜欢下象棋. 而且她特别喜欢象棋中的马. 她觉得马的跳跃方式很独特.(以日字格的方式跳跃) 小芳给了小美一张很大的棋盘,这个棋盘是一个无穷的笛卡尔坐标. 一开始\(time=0\) ...

  4. [JZOJ3385] [NOIP2013模拟] 黑魔法师之门 解题报告(并查集)

    Description 经过了16个工作日的紧张忙碌,未来的人类终于收集到了足够的能源.然而在与Violet星球的战争中,由于Z副官的愚蠢,地球的领袖applepi被邪恶的黑魔法师Vani囚禁在了Vi ...

  5. 2019.10.18模拟赛T3

    题目大意: 求$\sum\limits_{i=1}^n\sum\limits_{j=1}^n[lcm(i,j)>n](n\leq 10^{10})$的值. 题解: 这题貌似有n多种做法... 为 ...

  6. 2019.10.02模拟赛T3

    题目大意: 设$S(n,m)$为第二类斯特林数,$F_i$表示斐波那契数列第$i$项. 给定$n,R,K$,求$\sum\limits_{i=1}^{n}(\sum\limits_{m=1}^{R}F ...

  7. 2019.10.22 校内CSP%你赛

    我太难了 先说好没有代码T1 题目大意: 给定一些形如|ax+b|的式子,求最小的x使得它们的和最小. 算法一: 大家知道零点分段法 对于这n个式子我们有n+1个取值范围 使得展开这n个式子得到的新式 ...

  8. 【2019.8.6 慈溪模拟赛 T3】集合(set)(线段树上DP)

    线段树上\(DP\) 首先发现,每个数肯定是向自己的前驱或后继连边的. 则我们开一棵权值线段树,其中每一个节点记录一个\(f_{0/1,0/1}\),表示在这个区间左.右端点是否连过边的情况下,使这个 ...

  9. 【2019.8.11上午 慈溪模拟赛 T3】欢迎回来(back)(设阈值+莫队)

    设阈值 考虑对于询问的\(d\)设阈值进行分别处理. 对于\(d\le\sqrt{max\ d}\)的询问,我们可以\(O(n\sqrt{max\ d})\)预处理答案,\(O(1)\)输出. 对于\ ...

随机推荐

  1. 微信小程序——表单验证插件WxValidate的二次封装(终极版)

    微信小程序表单验证前面的两篇文章做的效果总感觉都有点不太友好,第一篇里的效果是将错误信息通过对话框形式弹出来,这种形式在web形式下早已经淘汰了:第二篇是一次性全部显示所有的错误,然后3秒后自动消失, ...

  2. json属性里面出现特殊字符怎么获取属性

    直接上代码. 这样的 获取这个object后需要获取里面的书属性,但是正常情况下是XX.属性名.但是属性名有特殊符号.这时候我们可以这样. XX['属性名']['属性名']....可以一直这样写 XX ...

  3. 浅谈——MySQL存储引擎

    博文大纲: 一.MyISAM存储引擎: 二.InnoDB存储引擎: 三.Memory存储引擎特点: 四.如何选择合适的存储引擎? 前言 数据库存储引擎是数据库底层软件组件,数据库管理系统(DBMS)使 ...

  4. navicat for mysql 连接 mysql 出现Client does not support authentication protocol requested by server解决方案

    一 .桌面左下角windows图标--搜索框内输入cmd,结果如图所示,点击cmd.exe,或者使用快捷键Windows键(在键盘上有个Windows标志的按键)+R输入cmd后回车. 二. 在出来的 ...

  5. Python学习笔记六(免费获取代理IP)

    为获取网上免费代理IP,闲的无聊,整合了一下,免费从三个代理网站获取免费代理IP,目的是在某一代理网站被限制时,仍可从可以访问的其他网站上获取代理IP.亲测可用哦!^_^  仅供大家参考,以下脚本可添 ...

  6. 《Web Development with Go》JWT认证满意版

    这个比昨晚的要满意, 认证放到中间件那里了. Mux使用的是gorilla, 中间件使用的是negroni, 启动是用的negroni.classic方法. package main import ( ...

  7. 07-Node.js学习笔记-路由

    路由 http://localhost:3000/index http://localhost:3000/login //路由是指客户端请求地址与服务器端程序代码的对应关系.简单的说,就是请求什么响应 ...

  8. Java描述设计模式(02):简单工厂模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景简介 1.引入场景 订餐流程简单描述 1).食品抽象类,规定食品的基础属性操作 2).鱼类,鸡肉类食品类扩展 3).订餐流程类,根 ...

  9. 硬盘容量统计神器WinDirStat

    最近遇到C盘快要爆满的问题,我的笔记本是128G SSD + 1t HDD,给C盘分配的空间是80G固态,由于平时疏远管理,造成了C盘臃肿,迁移一些软件,但还是没有太好的解决,这是上知乎发现有大神推荐 ...

  10. shell 中长命令的换行处理

    考察下面的脚本: emcc -o ./dist/test.html --shell-file ./tmp.html --source-map-base dist -O3 -g4 --source-ma ...