T1 lesson5!

开始以为是个无向图,直接不懂,跳去T2了。

之后有看了一眼发现可暴力,于是有了\(80pts\)。

发现这个图是有拓扑序的,于是可以用拓扑排序找最长路径。先找原图内在最长路径上的点,挨个删了跑拓扑排,看哪个最短。

正解太nb了待补。

\(code:\)

80pts

#include<bits/stdc++.h>
using namespace std; namespace IO{
inline int read(){
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
}
inline void write(int x,char sp){
char ch[20]; int len=0;
if(x<0){ putchar('-'); x=~x+1; }
do{ ch[len++]=(1<<4)+(1<<5)+x%10; x/=10; }while(x);
for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
}
inline int max(int x,int y){ return x<y?y:x; }
inline int min(int x,int y){ return x<y?x:y; }
inline void swap(int& x,int& y){ x^=y^=x^=y; }
inline void ckmax(int& x,int y){ x=x<y?y:x; }
inline void ckmin(int& x,int y){ x=x<y?x:y; }
} using namespace IO; const int NN=1e5+5,MM=5e5+5;
int t,n,m,mx,ans,pos,ban,idx,to[MM],nex[MM],head[NN],dis[NN],pre[NN];
int l,r,q[NN],in[NN],deg[NN];
bool vis[NN];
vector<int>vec;
inline void add(int a,int b){
to[++idx]=b; nex[idx]=head[a]; head[a]=idx; ++in[b];
} void topo(){
l=1; r=0;
for(int i=1;i<=n;i++)
if(!in[i]&&ban!=i) pre[i]=0, dis[i]=0, q[++r]=i;
while(l<=r){
int x=q[l++];
if(dis[x]>mx) mx=dis[x];
for(int i=head[x];i;i=nex[i]) if(in[to[i]]&&ban!=to[i]){
--in[to[i]];
if(!in[to[i]]){
pre[to[i]]=x;
dis[to[i]]=dis[x]+1;
q[++r]=to[i];
}
}
}
} signed main(){
FILE *R=freopen("johnny.in","r",stdin);
FILE *W=freopen("johnny.out","w",stdout);
t=read();
while(t--){
n=read(); m=read();
mx=ban=idx=0; vec.clear();
for(int i=1;i<=n;i++) in[i]=head[i]=vis[i]=0;
for(int a,b,i=1;i<=m;i++)
a=read(),b=read(), add(a,b);
for(int i=1;i<=n;i++) deg[i]=in[i];
topo(); ans=mx; pos=INT_MAX;
for(int i=1;i<=n;i++) if(dis[i]==mx){
int x=i;
while(x) vec.push_back(x), x=pre[x];
}
for(int i=0;i<vec.size();i++) if(!vis[vec[i]]){
ban=vec[i]; mx=0; vis[ban]=1;
for(int j=1;j<=n;j++) in[j]=deg[j];
for(int j=head[ban];j;j=nex[j]) --in[to[j]];
topo();
if(mx<ans||(mx==ans&&ban<pos)) ans=mx, pos=ban;
}
write(pos,' '); write(ans,'\n');
}
}


T2 贝尔数

模数不是质数就很搞。。

发现分解质因数后模数是五个一次的两位质数相乘,题目还给了模质数意义下的同余公式,于是可以先求出模五个质数意义下这一位贝尔数的值,然后再用中国剩余定理解个同余方程合并即可。

对每个质数可以先预处理前四十多个贝尔数,然后矩阵加速递推。

个人认为挺神的题(主要是数学跟矩阵都太菜了

\(code:\)

T2

#include<bits/stdc++.h>
#define int long long
using namespace std; namespace IO{
inline int read(){
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
}
inline void write(int x,char sp){
char ch[20]; int len=0;
if(x<0){ putchar('-'); x=~x+1; }
do{ ch[len++]=(1<<4)+(1<<5)+x%10; x/=10; }while(x);
for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
}
inline int max(int x,int y){ return x<y?y:x; }
inline int min(int x,int y){ return x<y?x:y; }
inline void swap(int& x,int& y){ x^=y^=x^=y; }
inline void ckmax(int& x,int y){ x=x<y?y:x; }
inline void ckmin(int& x,int y){ x=x<y?x:y; }
} using namespace IO; const int NN=1010,mod=95041567;
int T,n,nul,c[50][50],bell[50],pre[6],calc[6];
int pri[6]={0,31,37,41,43,47}; namespace Crt{
int exgcd(int a,int b,int& x,int& y){
if(!b){
x=1; y=0;
return a;
}
int g=exgcd(b,a%b,x,y),z;
z=y; y=x-a/b*y; x=z;
return g;
}
void init(){
bell[0]=1;
for(int i=0;i<50;i++) c[i][0]=1;
for(int i=1;i<50;i++) for(int j=1;j<=i;j++)
c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
for(int i=1;i<50;i++) for(int j=0;j< i;j++)
(bell[i]+=c[i-1][j]*bell[j]%mod)%=mod;
for(int i=1;i<6;i++){
int g=exgcd(pri[i],mod/pri[i],nul,pre[i]);
pre[i]=(pre[i]%mod+mod)%mod; pre[i]=(mod/pri[i])*pre[i]%mod;
}
}
int solve(){
int res=0;
for(int i=1;i<6;i++) (res+=pre[i]*calc[i])%=mod;
return res;
}
} using namespace Crt; namespace Matrix{
struct matrix{
int s[50][50];
void clr(){ memset(s,0,sizeof(s)); }
void pre(){ clr(); for(int i=0;i<50;i++) s[i][i]=1; }
void print(){for(int i=0;i<50;++i)for(int j=0;j<50;++j)write(s[i][j],j==49?'\n':' ');}
}mat[6],base[6];
matrix mul(matrix x,matrix y,int z){
matrix res; res.clr();
for(int i=0;i<50;i++)
for(int k=0;k<50;k++)
for(int j=0;j<50;j++)
(res.s[i][j]+=x.s[i][k]*y.s[k][j]%z)%=z;
return res;
}
void qpow(matrix& a,matrix b,int c,int d){
while(c){
if(c&1) a=mul(a,b,d);
b=mul(b,b,d);
c>>=1;
}
}
void prework(){
for(int i=1;i<6;i++){
for(int j=0;j<pri[i];j++) mat[i].s[1][j]=bell[j]%pri[i];
base[i].pre();
base[i].s[1][0]=base[i].s[0][pri[i]-1]=base[i].s[1][pri[i]-1]=1;
for(int j=1;j<pri[i]-1;j++) base[i].s[j+1][j]=1;
}
}
} using namespace Matrix; signed main(){
FILE *R=freopen("bell.in","r",stdin);
FILE *W=freopen("bell.out","w",stdout);
T=read(); init();
while(T--){
n=read(); prework();
for(int i=1;i<6;i++){
qpow(mat[i],base[i],n/pri[i],pri[i]);
calc[i]=mat[i].s[1][n%pri[i]];
}
write(solve(),'\n');
}
return 0;
}


T3 穿越广场

考完后发现这好像是个AC自动机套路题,但奈何时间久远,学的时候写的太快没多思考总结,于是SB了。

设\(f_{i,j,k,l}\)为\(DP\)到第\(i\)位,填了\(j\)个\(R\),在自动机中走到第\(k\)个节点,结束状态为\(l\)的方案数。

\(l\)为二进制状态,有两位。

于是有

\(\huge{f_{i,j,k,l} \to f_{i+1,j,to[k]['D'],l|end[to[k]['D']]}}\)

\(\huge{f_{i,j,k,l} \to f_{i+1,j+1,to[k]['R'],l|end[to[k]['R']]}}\)

初始状态\(f_{0,0,1,0}=1\)。

注意每个点继承它\(fail\)的状态即可。

\(code:\)

T3

#include<bits/stdc++.h>
#define int long long
#define ULL unsigned long long
using namespace std; namespace IO{
inline int read(){
char ch=getchar(); int x=0,f=1;
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
}
inline void write(int x,char sp){
char ch[20]; int len=0;
if(x<0){ putchar('-'); x=~x+1; }
do{ ch[len++]=(1<<4)+(1<<5)+x%10; x/=10; }while(x);
for(int i=len-1;~i;--i) putchar(ch[i]); putchar(sp);
}
inline int max(int x,int y){ return x<y?y:x; }
inline int min(int x,int y){ return x<y?x:y; }
inline void swap(int& x,int& y){ x^=y^=x^=y; }
inline void ckmax(int& x,int y){ x=x<y?y:x; }
inline void ckmin(int& x,int y){ x=x<y?x:y; }
} using namespace IO; const int NN=110,p=1e9+7;
int t,n,m,ext,ans,f[NN<<1][NN][NN<<1][4];
char ch[NN]; namespace AC_automaton{
int root,tot,to[NN<<1][2],fail[NN<<1],end[NN<<1];
void insert(char *s){
int len=strlen(s),u=1;
for(int i=0;i<len;i++){
int now=(s[i]=='R');
if(!to[u][now]) to[u][now]=++tot, end[tot]=0;
u=to[u][now];
}
end[u]=root?2:1;
if(!root) root=1;
}
void build(){
queue<int>q;
if(to[root][0]) q.push(to[root][0]), fail[to[root][0]]=root;
else to[root][0]=root;
if(to[root][1]) q.push(to[root][1]), fail[to[root][1]]=root;
else to[root][1]=root;
while(!q.empty()){
int u=q.front(); q.pop();
end[u]|=end[fail[u]];
if(to[u][0]) fail[to[u][0]]=to[fail[u]][0], q.push(to[u][0]);
else to[u][0]=to[fail[u]][0];
if(to[u][1]) fail[to[u][1]]=to[fail[u]][1], q.push(to[u][1]);
else to[u][1]=to[fail[u]][1];
}
}
} using namespace AC_automaton; signed main(){
FILE *R=freopen("square.in","r",stdin);
FILE *W=freopen("square.out","w",stdout);
t=read();
while(t--){
m=read(); n=read(); tot=1; root=0; ext=n+m; ans=0;
memset(f,0,sizeof(f));
memset(to,0,sizeof(to));
memset(fail,0,sizeof(fail));
scanf("%s",ch); insert(ch);
scanf("%s",ch); insert(ch);
build(); f[0][0][1][0]=1;
for(int i=0;i<ext;i++)
for(int j=0;j<=m;j++){
if(j>i||i-j>n) continue;
for(int k=1;k<=tot;k++)
for(int u=0;u<4;u++){
(f[i+1][j ][to[k][0]][u|end[to[k][0]]]+=f[i][j][k][u])%=p;
(f[i+1][j+1][to[k][1]][u|end[to[k][1]]]+=f[i][j][k][u])%=p;
}
}
for(int i=1;i<=tot;i++) (ans+=f[ext][m][i][3])%=p;
write(ans,'\n');
}
return 0;
}


T4 舞动的夜晚

先跑最大流,然后在残量网络上跑\(tarjan\),如果边在\(SCC\)里说明它没有影响。

改的有点ex,待补

2021.9.21考试总结[NOIP模拟58]的更多相关文章

  1. 2021.8.21考试总结[NOIP模拟45]

    T1 打表 由归纳法可以发现其实就是所有情况的总和. $\frac{\sum_{j=1}^{1<<k}(v_j-v_{ans})}{2^k}$ $code:$ 1 #include< ...

  2. 2021.7.21考试总结[NOIP模拟22]

    终于碾压小熠了乐死了 T1 d 小贪心一波直接出正解,没啥好说的(bushi 好像可以主席树暴力找,但我怎么可能会呢?好像可以堆优化简单找,但我怎么可能想得到呢? 那怎么办?昨天两道单调指针加桶,我直 ...

  3. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  4. 2021.9.13考试总结[NOIP模拟52]

    T1 路径 考虑每一位的贡献,第$i$位每$2^i$个数会变一次,那么答案为$\sum_{i=1}^{log_2n} \frac{n}{2^i}$. $code:$ 1 #include<bit ...

  5. 2021.8.11考试总结[NOIP模拟36]

    T1 Dove玩扑克 考场并查集加树状数组加桶期望$65pts$实际$80pts$,考后多开个数组记哪些数出现过,只扫出现过的数就切了.用$set$维护可以把被删没的数去掉,更快. $code:$ 1 ...

  6. 2021.7.29考试总结[NOIP模拟27]

    T1 牛半仙的妹子图 做法挺多的,可以最小生成树或者最短路,复杂度O(cq),c是颜色数. 我考场上想到了原来做过的一道题影子,就用了并查集,把边权排序后一个个插入,记录权值的前缀和,复杂度mlogm ...

  7. 2021.7.15考试总结[NOIP模拟16]

    ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...

  8. 2021.9.14考试总结[NOIP模拟53]

    T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...

  9. 2021.9.12考试总结[NOIP模拟51]

    T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...

随机推荐

  1. JDK7u21反序列化详解

    目录 前言 环境 倒序分析 TemplatesImpl AnnotationInvocationHandler HashMap 总结 前言 听说jdk7u21的反序列化涉及的知识量很多,很难啃,具体来 ...

  2. Web GIS 航拍实现的智慧园区数字孪生应用

    前言 随着智慧城市建设的不断发展,智慧园区作为智慧城市的先行区,其覆盖区域越来越大,产值越来越集中,对于园区数字化建设和智能化管理的诉求也愈加强烈.园区数字化管理是以实现园区多维度业务数据汇聚.融合. ...

  3. 【第六篇】- Maven 仓库之Spring Cloud直播商城 b2b2c电子商务技术总结

    Maven 仓库 在 Maven 的术语中,仓库是一个位置(place). Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库. 在 Maven 中,任何一个依赖.插件或者项目构建的输出 ...

  4. 一文搞懂如何使用Node.js进行TCP网络通信

    摘要: 网络是通信互联的基础,Node.js提供了net.http.dgram等模块,分别用来实现TCP.HTTP.UDP的通信,本文主要对使用Node.js的TCP通信部份进行实践记录. 本文分享自 ...

  5. BZOJ_1008 越狱(快速幂)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1008 Description 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教 ...

  6. 查看Win10商店应用更新日期

    查看Win10商店应用更新日期 需要用到一个工具--WP Snitch,网址 https://wpsnitch.appspot.com/ 打开网址后他会给出一个示例,比如给出的是 https://ww ...

  7. AT3945-[ARC092D]Two Faced Edges【dfs】

    正题 题目链接:https://www.luogu.com.cn/problem/AT3945 题目大意 \(n\)个点\(m\)条边的一张图,对于每条边求它翻转后强连通分量数量是否变化. \(1\l ...

  8. 从产业链、架构和技术三个层面,看元宇宙与RPA的发展关系

    你可能还不知道,元宇宙也将带动RPA高速发展 一文读懂RPA如何赋能元宇宙,虚拟空间更需要RPA无处不在 三个层面,解读元宇宙如何利好RPA行业发展 从产业链.架构和技术三个层面,看元宇宙与RPA的发 ...

  9. 14-Java锁的概述

    14-锁的概述 乐观锁与悲观锁 ​ 乐观锁与悲观锁是数据库中引入的名词,但是在并发包里也引入了类似的思想,在这里我们还是有必要需要了解一下. ​ 悲观锁指数据被外界修改持保守态度,认为数据会很容易被其 ...

  10. 理解ASP.NET Core - 配置(Configuration)

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 配置提供程序 在.NET中,配置是通过多种配置提供程序来提供的,包括以下几种: 文件配置提供程 ...