bzoj 4386: [POI2015]Wycieczki
这题什么素质,爆long long就算了,连int128都爆……最后还是用long double卡过的……而且可能是我本身自带大常数吧,T了好长时间……
先说一下超级汇点的计数吧,先说结论:
1.将所有点(此题中只有一级点)向一个超级汇点0连边,将矩阵乘n次,相应的f[i][j]即为从i到j的走n步方案数,f[i][0]为i到0走n步的方案数,若在给他乘一个ans矩阵(ans在前),则f[0][0]-n(点数)为所有长度等于n(指数)的路径的方案数。ans矩阵为0向所有其他点连边。
2.若在1中,将0想自己连边,则每次相乘都会积累,最终得出的即为所有长度小于等于n的路径方案数。
具体可以这样理解:
ans矩阵相当于从超级汇点出发走一步,每乘一个base矩阵,相当于走一步,乘了n次后,相当于走n步,但是还要再乘一个base,相当于各点回到0,而计数器中仍保留着从0走出的方案数,此时f[0][0]-点数即为答案。(这种问题自己手模一下会更容易理解吧)。
然后是题解:
边权只有1,2,3三种,考虑拆点(在‘迷路’中也用到了同样的方法),将一个点分为三级,$get(int po,int w){return (po-1)*3+w;}$,将每个点的第一级向第二级连边,第二级向第三级连边,对于一条a->b,长度为w的边,从a的第w级向b的第一级连长度为1的边。
代码实现:
for(int i=;i<=m;i++)
{
a=read(),b=read(),c=read();
cs.m[get(a,c)][get(b,)]++;
}
for(int i=;i<=n;i++)
{
cs.m[get(i,)][get(i,)]++;
cs.m[get(i,)][get(i,)]++;
}
这样就得到了一个初始矩阵,构造出ans矩阵,显然可以二分枚举长度解决,但是复杂度比较高会T,考虑倍增,提前预处理出初始矩阵乘$2^i$后的矩阵,像LCA那样搞就可以了。
然而这道题还有几个坑点:
方案数乘的时候会爆longlong(如果你打的恶心点连__int128都会爆),可以加判断,个人感觉比较麻烦,于是就用了double,还会爆?丝毫不慌还有long double。
然后就T了,用lemon测了一下,跑了一百多秒,好在都跑对了,其实这不是long double的锅,和我自带的大常数关系也不大,在预处理倍增数组时我固定给他求到了65,导致时间比较长,其实可以记录一下:
for(int i=;i<=;i++,imax++){F[i]=F[i-]*F[i-];if((ans*F[i]).count()>k)break;}
然后就A了,跑得还挺快。其实我还是搞不懂为啥会差这么多,固定求到65复杂度也是$n^3log_n$啊……
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N n*3
#define LD long double
#define LL long long
using namespace std;
int n,m;LL k;
struct jz
{
LD m[121][121];
LD count() {return m[0][0]-n;}
}cs,ans,F[70];
jz operator * (jz &a,jz &b)
{
jz ans;
for(int i=0;i<=N;i++)
for(int j=0;j<=N;j++)
ans.m[i][j]=0;
for(int i=0;i<=N;i++)
for(int j=0;j<=N;j++)
for(int k=0;k<=N;k++)
ans.m[i][j]+=a.m[i][k]*b.m[k][j];
return ans;
}
inline int get(const register int po,const register int w){return (po-1)*3+w;}
inline LL read()
{
LL s=0;char a=getchar();
while(a<'0'||a>'9')a=getchar();
while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
return s;
}
signed main()
{
// freopen("10.in","r",stdin); n=read(),m=read(),k=read();
int a,b,c;
for(int i=1;i<=m;i++)
{
a=read(),b=read(),c=read();
cs.m[get(a,c)][get(b,1)]++;
}
for(int i=1;i<=n;i++)
{
cs.m[get(i,1)][get(i,2)]++;
cs.m[get(i,2)][get(i,3)]++;
}
LL imax=1;
cs.m[0][0]=1;
for(int i=1;i<=n;i++)cs.m[get(i,1)][0]++;
for(int i=1;i<=n;i++)ans.m[0][get(i,1)]=1;
F[0]=cs;
for(int i=1;i<=65;i++,imax++){F[i]=F[i-1]*F[i-1];if((ans*F[i]).count()>k)break;}
if((ans*F[imax]).count()<k){cout<<-1<<endl;return 0;}
LL num=0;
for(int i=imax;i>=0;i--)
{
jz tm=ans*F[i];
if(tm.count()<k){num+=1ll<<i;ans=ans*F[i];}
}
cout<<num<<endl;
}
bzoj 4386: [POI2015]Wycieczki的更多相关文章
- BZOJ 4386 Luogu P3597 [POI2015]Wycieczki (矩阵乘法)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4386 (luogu) https://www.luogu.org/pro ...
- BZOJ 4385: [POI2015]Wilcze doły
4385: [POI2015]Wilcze doły Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 648 Solved: 263[Submit][ ...
- BZOJ 4384: [POI2015]Trzy wieże
4384: [POI2015]Trzy wieże Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 217 Solved: 61[Submit][St ...
- Bzoj 3747: [POI2015]Kinoman 线段树
3747: [POI2015]Kinoman Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 553 Solved: 222[Submit][Stat ...
- BZOJ 3747 POI2015 Kinoman 段树
标题效果:有m点,每个点都有一个权值.现在我们有这个m为点的长度n该序列,寻求区间,它仅出现一次在正确的点区间内值和最大 想了很久,甚至神标题,奔说是水的问题--我醉了 枚举左点 对于每个请求留点右键 ...
- BZOJ 4380 [POI2015]Myjnie | DP
链接 BZOJ 4380 题面 有n家洗车店从左往右排成一排,每家店都有一个正整数价格p[i]. 有m个人要来消费,第i个人会驶过第a[i]个开始一直到第b[i]个洗车店,且会选择这些店中最便宜的一个 ...
- BZOJ4386 [POI2015]Wycieczki 矩阵+倍增
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4386 题解 一眼就可以看出来是邻接矩阵快速幂. 可是这里的边权不为 \(1\).不过可以发现, ...
- BZOJ4386 : [POI2015]Wycieczki
将每个点拆成三个点,并将转移转化为矩阵乘法,然后倍增即可求出第$k$短路的长度,注意对爆long long情况的处理. 时间复杂度$O(n^3\log k)$. #include<cstdio& ...
- BZOJ 3747 POI2015 Kinoman
因为上午没有准备够题目,结果发现写完这道题没题可写了QAQ 又因为这道题范围是100w,我写了发线段树,以为要T,上午就花了一个小时拼命卡常数 结果下午一交居然过了QAQ 我们考虑枚举L,求最大R使得 ...
随机推荐
- SSH 框架controller向jsp传递List jsp中使用el表达式获取
mvc可以使用ModelAndViev传递数据选择跳转的视图 controller中的代码, 把一个模拟的表单studentListSimulate传给ModelAndView @RequestMap ...
- idea中使用本地jar包
一个maven项目中使用到了taobao-sdk-java-auto_1455552377940-20160422.jar包,项目是直接导入的jar包而没用用maven的形式导入,导致在idea编辑时 ...
- 2019.10.21 csp-s模拟测试81 反思总结
T1: 把每一行状压,按行DP.设fi,j,k,i表示第几行,j是当前行的1覆盖状态,k是当前行选择按钮的状态.转移的时候枚举j和k,再枚举下一层的按钮选择情况l.如果l和j可以全覆盖当前层则转移合法 ...
- ADSL pppoe 拔号工具rp-pppoe
rp-pppoe 目前在各大发行版本都是存在的,比如Redhat/Fedora.红旗.Slackware.Debian.SuSE等系统,都是采用这个拔号软件,所以您大可不必为下载源码编译安装.只需要在 ...
- QT_强杀进程
#ifdef WIN32 bool res = false; HANDLE hToolHelp32Snapshot; hToolHelp32Snapshot = CreateToolhelp32Sna ...
- web前端学习(二)html学习笔记部分(4)--audio和video文件播放
1.2.10 html5音频 1.2.10.1 HTML5音频播放 本课主要讲解HTML5播放音频 <!--<button onclick="clickA"> ...
- loadrunner11录制为空的解决办法(win7+chrome最新版本)
参考:https://www.cnblogs.com/zhang-zhi/archive/2018/09/10/9622605.html loadrunner11在win7中,使用chrome浏览器的 ...
- NYoj 155最短路
//dij #include<stdio.h> #include<string.h> #include<queue> using namespace std; #d ...
- Winform实现调用asp.net数据接口实例
本文实例讲述了Winform实现调用asp.net数据接口的方法,分享给大家供大家参考.具体实现方法如下: 一.问题: 最近一个WPF项目需要改写成android项目,思路是在asp.net项目中编写 ...
- 解决listview点击item失效
开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了 ...