题目描述
  要开运动会了,Freda承担起了制作全校旗帜的工作。旗帜的制作方法是这样的:Freda一共有C种颜色的布条,每种布条都有无数个,你可以认为这些布条的长、宽、厚都相等,只有颜色可能不同。每个旗帜都是由一些布条横向拼接起来的,如图所示,图上所示的是一面红、黄、蓝三种颜色布条拼接的旗帜:

就不给你看图

布条数目不同的旗帜显然是不同的。对于布条数目都为T的两面旗帜,如果存在从左到右第i(0<i<=N)个布条颜色不同,那么就认为这两面旗帜是不同的。旋转或翻转后才相同的旗帜被认为是不同的旗帜,比方说,“红黄蓝”和“蓝黄红”被认为是不同的旗帜。有的时候,一些颜色放在相邻的位置上会显得很不好看,比方说红色和绿色放在一起就很不好看。作为一个完美主义者,Freda可不想这样。
  全校共有N个班级,不同的班级必须使用不同的旗帜,Freda也就需要制作N面不同的旗帜了。和谐起见,Freda想让使用布条数目最多的那面旗帜使用的布条数目最少,请你帮助Freda计算一下,在避免了不好看的情况之后,使用布条数目最多的那面旗帜最少要用多少布条。
输入格式
  第一行两个整数N,C,表示班级的数目和Freda拥有C种颜色的布条。
  接下来C行,每行一个长度为C的字符串,每个字符都为’0’或’1’,第i行第j个字符表示第i种颜色和第j种颜色是否能够相邻。如果能,第i行第j个字符为’1’,否则为’0’.保证第i行第j个字符与第j行第i个字符相同。
输出格式
  一行一个整数,表示制作了N面不同的旗帜的情况下,使用布条数目最多的那面旗帜最少需要多少布条。
输入样例
  10 2
  11
  11
输出样例
  3
提示
样例解释
  我们分别制作如下旗帜:
  (1),(2),(1,1),(1,2),(2,1),(2,2),(1,1,1),(1,1,2),(1,2,1),(1,2,2)
  用布条最多的旗帜所用布条为3.
数据范围与约定
  对于50%的数据,保证0 < N <= 50000.
  对于80%的数据,保证0 < N <= 10^9.
  对于100%的数据,保证0 < N <= 10^18, 0 < C <=10且数据一定有解.

分析

这个题也想了半天,其实是因为睡着了

设f[i][j]表示有旗帜长度为i的时候,第j种颜色开头的方案数,V[i][j]表示i后面是否可以接j

那么就有

$$f[i][j]=\sum_{k=1}^{c}f[i-1][k]*V[j][k]$$

发现这个东西可以反手一个矩阵加速闷声发大财,所以对于每一个长度,我们可以很快求出这个长度下的方案数

而且我们还可以发现长度与方案数是单调递增的,所以可以二分长度,求出这个长度下的方案数的总和,看它是否能大于要求的方案数n

当然,方案数统计出来可能会炸longlong,我们可以重新定义一个类似longlong的结构体,结构体里除了longlong还要再来一个标记,标记这个数是否超过了n

Code

#include<cstdio>
#include<cstring>
long long n;int c;
struct ll{long long num;bool fl;};
struct node{ll mat[][];}a,g;
ll operator +(ll a,ll b){return (ll){a.num+b.num,a.fl||b.fl||(a.num+b.num>=n)};}
ll operator *(ll a,ll b)
{
if((a.num==&&!a.fl)||(b.num==&&!b.fl))return (ll){,};
return (ll){a.num*b.num,a.fl||b.fl||(double(a.num)*double(b.num)>=double(n))};
}
node operator *(node a,node b)
{
node res;memset(res.mat,,sizeof res.mat);
for(int i=;i<=c+;i++)for(int j=;j<=c+;j++)for(int k=;k<=c+;k++)
res.mat[i][k]=res.mat[i][k]+a.mat[i][j]*b.mat[j][k];
return res;
}
node qp(node a,node g,long long k)
{while(k){if(k&)a=a*g;g=g*g;k>>=;}return a;}
int main()
{
scanf("%lld%d",&n,&c);
for(int i=;i<=c;i++)for(int j=;j<=c;j++)scanf("%1lld",&g.mat[i][j].num);
for(int i=;i<=c;i++)a.mat[][i].num=,g.mat[i][c+].num=;g.mat[c+][c+].num=;
long long l=,r=n,mid,ans;
while(l<=r)
{
mid=(l+r)>>;
node nw=qp(a,g,mid);ll sum=nw.mat[][c+];
if(sum.fl)ans=mid,r=mid-;
else l=mid+;
}
printf("%lld\n",ans);
}

【CSP模拟赛】Freda的旗帜的更多相关文章

  1. CSP模拟赛游记

    时间:2019.10.5 考试时间:100分钟(连正式考试时间的一半还没有到)题目:由于某些原因不能公开. 由于第一次接触NOIinux系统所以连怎么建文件夹,调字体,如何编译都不知道,考试的前半小时 ...

  2. 【CSP模拟赛】Freda的迷宫(桥)

    题目描述 Freda是一个迷宫爱好者,她利用业余时间建造了许多迷宫.每个迷宫都是由若干房间和走廊构成的,每条走廊都连接着两个不同的房间,两个房间之间最多只有一条走廊直接相连,走廊都是双向通过.  黄昏 ...

  3. CSP模拟赛2游记

    这次由于有课迟到30min,了所以只考了70min. 调linux配置调了5min,只剩下65min了. T1:有点像标题统计,但要比他坑一点,而且我就被坑了,写了一个for(int i=1;i< ...

  4. 【csp模拟赛4】基站建设 (station.cpp)

    [题目描述] 小 Z 的爸爸是一位通信工程师,他所在的通信公司最近接到了一个新的通 信工程建设任务,他们需要在 C 城建设一批新的基站. C 城的城市规划做得非常好,整个城市被规整地划分为 8 行 8 ...

  5. 【CSP模拟赛】starway(玄学建边 最小生成树)

    问題描述 小w伤心的走上了 Star way to heaven.   到天堂的道路是一个笛卡尔坐标系上一个n×m的长方形通道(顶点在(0,0))和(n,m)),小w从最左边任意一点进入,从右边任意一 ...

  6. 【CSP模拟赛】Confess(数学 玄学)

    题目描述 小w隐藏的心绪已经难以再隐藏下去了.小w有n+ 1(保证n为偶数)个心绪,每个都包含了[1,2n]的一个大小为n的子集.现在他要找到隐藏的任意两个心绪,使得他们的交大于等于n/2. 输入描述 ...

  7. 【CSP模拟赛】Adore(状压dp 二进制)

    题目描述 小w偶然间见到了一个DAG.这个DAG有m层,第一层只有一个源点,最后一层只有一个汇点,剩下的每一层都有k个节点.现在小w每次可以取反第i(1<i<n-1)层和第i+1层之间的连 ...

  8. 【CSP模拟赛】凤凰院凶真(最长公共上升子序列)

    题目描述 α世界线.凤凰院凶真创立了反抗SERN统治的组织“瓦尔基里”.为了脱离α线,他需要制作一个世界线变动率测量仪. 测量一个世界线相对于另一个世界线的变动率,实质上就是要求出这两个世界线的最长公 ...

  9. 【CSP模拟赛】天才绅士少女助手克里斯蒂娜(线段树&读入优化&输出优化)

    题面描述 红莉栖想要弄清楚楼下天王寺大叔的显像管电视对“电话微波炉(暂定)”的影响.选取显像管的任意一个平面,一开始平面内有个n电子,初始速度分别为vi,定义飘升系数为 $$\sum_{1\leqsl ...

随机推荐

  1. C#生成唯一不重复订单号帮助类

    1.使用场景 通常,在做一些表单的功能时,需要生成唯一不重复的订单单号,本文提供的帮助类可以适合大多数场景的单号生成使用,拿来即用,方便快捷无重复.而且,在高并发的情况下也是可以使用的. 之前看到有人 ...

  2. 并发编程--一堆锁,GIL,同步异步,Event事件

    目录 一堆锁 死锁现象(*****) 递归锁 RLock (了解) 信号量 (了解) GIL(*****) 什么时GIL锁 为什么需要GIL锁 Cpython解释器与GC的问题 GIL锁带来的问题 多 ...

  3. 2019-08-01 JQuery事件

    Jquery简单的事件 l blur(fn) 当失去焦点时 l change(fn) 当内容发生改变时 l click(fn) 当鼠标单击时 l dblclick 当鼠标双击时 l focus(fn) ...

  4. Beego 学习笔记9:Boostrap使用介绍

    BootStrap布局 1>     下载地址: http://v3.bootcss.com/getting-started/#download 根据自己的需要,下载不同的版本.我这里使用的是1 ...

  5. jQuery源码二之extend的实现

    extend是jQuery中一个比较核心的代码,如果有查看jQuery的源码的话,就会发现jQuery在多处调用了extend方法. 作用 对任意对象进行扩展 扩展某个实例对象 对jquery本身的实 ...

  6. JavaScript 函数(二)

    一.匿名函数 1.匿名函数 没有名字的函数即称为匿名函数. 2.使用方法 a.将匿名函数赋值给一个变量,这样就可以通过变量进行调用 b.匿名函数自调用 3.关于自执行函数(匿名函数自调用)的作用:防止 ...

  7. linux ssh scp免密码

    1.首先登入一台linux服务器做为母机(即登入其他linux系统用这台做为入口):执行一行命令生成key文件:ssh-keygen -t rsa 2.在母机上,进入/root/.ssh目录,找到id ...

  8. SPRINGBOOT注解最全详解(

    #     SPRINGBOOT注解最全详解(整合超详细版本)          使用注解的优势:               1.采用纯java代码,不在需要配置繁杂的xml文件           ...

  9. windows+jenkins+springboot自动构建并后台执行jar

    本文只讲述如何在windows环境下,搭建jenkins并使用,至于概念的东西请自行百度. 好了,直入主题,本人使用 jenkins.war 包进行部署,我们需要准备如下几个: openjdk8    ...

  10. List加载因子和扩容因子

    List.Map.set的加载因子,默认初始容量和扩容增量 首先,这三个概念说下.初始大小,就是创建时可容纳的默认元素个数:加载因子,表示某个阀值,用0~1之间的小数来表示,当已有元素占比达到这个阀值 ...