CF917C. Pollywog

题目描述

Solution

看完题,基本的方向就是状压DP。

因为每次都是最左边的青蛙跳至多kkk步,容易发现任意两个青蛙之间的距离始终小于kkk。

因此可以把连续kkk个位置的空闲状态压在(kx)≤70\binom{k}{x}\leq70(xk​)≤70个二进制数中,用f[i][j]f[i][j]f[i][j]表示i...i+k−1i...i+k-1i...i+k−1的青蛙存在状态为jjj的最小代价,并保证iii位置有青蛙(避免冗余的重复状态),这样转移的时候就枚举iii位置的青蛙跳几步ttt,并把j′=(jxor1)or2tj'=(j\;xor\;1)\;or\;2^t\;j′=(jxor1)or2t不断右移,保证第一个位置是111,设移了ppp位,便从f[i][j]f[i][j]f[i][j]转移至f[i+p+1][j′>>p]f[i+p+1][j'>>p]f[i+p+1][j′>>p]。

这样的时间复杂度是O(nk(kx))O(nk\binom{k}{x})O(nk(xk​))的,看似是一个很不错的跳板,但事实上这种方法及其误导(我在这里卡了一万年,雾) ,事实上我们不需要用上述方法避免状态冗余,只需要在第iii个位置上没青蛙,即((jand1)=0)((j\;and\;1)=0)((jand1)=0)时的转移变为f[i][j]−>f[i+1][j>>1]f[i][j]->f[i+1][j>>1]f[i][j]−>f[i+1][j>>1]。那么,就不用计算所谓的ppp了,可以直接实现从f[i][j]−>f[i+1][j′]f[i][j]->f[i+1][j']f[i][j]−>f[i+1][j′]的转移。

这样我们每次的转移都是从i−>i+1i->i+1i−>i+1的,可以用矩乘优化。

对于特殊的位置iii,用矩乘算到f[i][...]f[i][...]f[i][...]之后暴力枚举转移,加额外贡献,然后继续矩乘转移即可。

时间复杂度O((kx)3lg⁡n+q(kx)2)O(\binom{k}{x}^3\lg n+q\binom{k}{x}^2)O((xk​)3lgn+q(xk​)2)

Code

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se secondusing namespace std;template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int MAXN=600005;
const ll INF=1ll<<60;
/*--------------------------------------------------------------------*/
inline int read()
{int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f;
}
int c[10],id[305],to[305],cnt=0;
PR p[105];
struct Matrix
{int n;ll A[71][71];Matrix(int n1=70) { n=n1; for (int i=1;i<=n;i++)for (int j=1;j<=n;j++) A[i][j]=(i==j?0:INF);}Matrix operator * (Matrix b){Matrix ans;for (int i=1;i<=n;i++) ans.A[i][i]=INF;for (int k=1;k<=n;k++)for (int i=1;i<=n;i++)for (int j=1;j<=n;j++) upmin(ans.A[i][j],A[i][k]+b.A[k][j]);return ans;} Matrix operator ^ (int y){if (!y) return Matrix();Matrix ret=*this,ans;for (;y;y>>=1){if (y&1) ans=ans*ret;ret=ret*ret;}return ans;}
} nxt,ans;
int main()
{int x=read(),k=read(),n=read(),q=read();for (int i=1;i<=k;i++) c[i]=read();for (int i=1;i<=q;i++) p[i].fi=read(),p[i].se=read();sort(p+1,p+q+1);for (int i=1;i<1<<k;i++) if (__builtin_popcount(i)==x) id[i]=++cnt,to[cnt]=i;for (int i=1;i<=cnt;i++){for (int j=1;j<=cnt;j++) nxt.A[i][j]=INF;if (!(to[i]&1)) { nxt.A[i][id[to[i]>>1]]=0; continue; }for (int j=1;j<=k;j++){if ((to[i]>>j)&1) continue;nxt.A[i][id[(to[i]|(1<<j))>>1]]=c[j];}}ll sum=0; int now=1;for (int i=1;i<=q;i++){if (p[i].fi>n-x) { sum+=p[i].se; continue; }ans=ans*(nxt^(p[i].fi-now)),now=p[i].fi;for (int j=1;j<1<<k;j+=2)if (id[j])for (int t=1;t<=cnt;t++) ans.A[t][id[j]]+=p[i].se;}ans=ans*(nxt^(n-x+1-now));printf("%lld\n",ans.A[1][1]+sum);return 0;
}

CF917C. Pollywog相关推荐

  1. 2018暑期做题部分整合

    <Matrix>(HDU) 题意:n*m矩阵,每个点可黑可白,问有多少种方案使矩阵至少有A行B列全黑. 思路:第一反应当然是容斥,但是发现a+1行全黑的方案,并不是恰被a行全黑的方案多算a ...

最新文章

  1. elementary OS 6 评测!
  2. 《Cracking the Coding Interview》——第18章:难题——题目3
  3. JDK,JRE,JVM三者的关系
  4. 【FFMPEG中PTS与DTS统一转换为毫秒】
  5. linux内核支持的加密算法,Linux Kernel(Android) 加密算法总结(三)-应用程序调用内核加密算法接口...
  6. 贵州农信凭证打印小程序_我的医保凭证小程序入口
  7. FastDFS(提升磁盘IO性能的几个技巧 FastDFS 5.04之IO读事件)
  8. 布林通道参数用20还是26_布林通道(BOLL)策略的投资效果如何?
  9. webstorm简单介绍,webstrom基本使用
  10. Python 编写自动化工具
  11. Android网络收集和ping封装库
  12. 关于分布式服务中的中间件技术入门概述
  13. SMARTFORM打印程序模板
  14. 发现一款好用的 java web报表工具
  15. 计算机用什么配置好电脑,买电脑主要看哪些配置 决定电脑好坏的关键
  16. c站官网(c站官网客户端下载苹果)
  17. 阿里云推出“通达云OA”办公系统 基于钉钉的移动OA应用
  18. 手把手教你写《雷神》游戏(三)
  19. Unable to find the VMX binary ‘D:\新建文件夹1\vmware-vmx.exe‘.
  20. 面试平安科技--二面

热门文章

  1. 如果你没有时间读书,至少要保留这个习惯
  2. 学好数学建模,走哪买菜都不怕!
  3. 通过Python实现马尔科夫链蒙特卡罗方法的入门级应用
  4. vue 3.0 正式版_Vuejs 3 Release:One Piece. Vuejs 3.0 正式版发布!代号:海贼王
  5. mysql 备份 master_如何配置MYSQL的MASTER---SLAVE复制备份?
  6. 高等学校计算机科学与技术教材:tcp/ip网络编程技术基础,TCP/IP网络编程技术基础...
  7. java实现权限_Java实现常用权限控制算法
  8. yii 使用 有赞sdk_有赞ABTest系统:数据驱动增长实践
  9. python公式_Python读取excel文件中带公式的值的实现
  10. python时钟罗盘酷炫代码_抖音上的时钟屏保,被我改造完用来表白