hdu4352 XHXJ's LIS[数位DP套状压DP+LIS$O(nlogn)$]
统计$[L,R]$内LIS长度为$k$的数的个数,$Q \le 10000,L,R < 2^{63}-1,k \le 10$。
首先肯定是数位DP。然后考虑怎么做这个dp。如果把$k$记录到状态里没有用。需要找到有效方法统一的表示前面填好的数的特点方便之后的填数。
回顾LIS过程,当前数结尾的LIS是前面比他小的数的LIS中的max+1,但是没有办法记录下来,因为如果记录下前面以数字$0\sim 9$结尾的maxLIS的话空间不够。
尝试换一种表示方法。回顾LIS的$O(nlogn)$做法,发现维护了一个$g$数组表示长度$i$的LIS结尾最小$g[i]$,这个数组是单调增的。
这是发现可以方便记录——用一个数$S$,把二进制第$g[i]$位$\text{or}$到$S$上去。这样,$S$中是$1$的位置从小到大写下来就是$g$数组了。
设$f(len,S,n,lead,limit)$,$S$是之前填好的数的$g$数组,$n$是前面的最长LIS长度。枚举当前位填啥,通过二分确定新的$S$,然后边界判一下是否$n=k$就好了。
code细节:
- 注意到$k$是相互独立的,可以分别进行统计,$f[k][...]$表示满足……条件(见上)之下、LIS长度为$k$的数的个数。
- 注意判断前导0。
- 加了一些剪枝,虽然并没有什么用。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define dbg(x) cerr << #x << " = " << x <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
ll f[][][<<][],b[],tot;
ll L,R;
int T,k;
ll dp(int len,int S,int n,int lead,int limit){
if(!len)return n==k;
if(n>k||n+len<k)return ;
if(!limit&&~f[k][len][S][lead])return f[k][len][S][lead];
int num=limit?b[len]:;ll ret=;
if(lead){
ret+=dp(len-,S,n,lead,limit&&!num);
for(register int i=;i<=num;++i)ret+=dp(len-,<<i,,,limit&&i==num);
}
else{
int a[]={},m=;
for(register int i=;i<=;++i)if(S&(<<i))a[++m]=i;
for(register int i=;i<=num;++i){
int pos=lower_bound(a+,a+m+,i)-a;
if(pos>m)ret+=dp(len-,S|(<<i),n+,,limit&&i==num);
else ret+=dp(len-,S^(<<a[pos])|(<<i),n,,limit&&i==num);
}
}
return limit?ret:f[k][len][S][lead]=ret;
}
inline ll solve(ll x){
tot=;while(x)b[++tot]=x%,x/=;
return dp(tot,,,,);
} int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(T);memset(f,-,sizeof f);
for(register int i=;i<=T;++i)
read(L),read(R),read(k),printf("Case #%d: %lld\n",i,solve(R)-solve(L-));
return ;
}
总结:还是那句话,用有效的方法表示好填好的数的性质。
hdu4352 XHXJ's LIS[数位DP套状压DP+LIS$O(nlogn)$]的更多相关文章
- 树形DP和状压DP和背包DP
树形DP和状压DP和背包DP 树形\(DP\)和状压\(DP\)虽然在\(NOIp\)中考的不多,但是仍然是一个比较常用的算法,因此学好这两个\(DP\)也是很重要的.而背包\(DP\)虽然以前考的次 ...
- dp乱写1:状态压缩dp(状压dp)炮兵阵地
https://www.luogu.org/problem/show?pid=2704 题意: 炮兵在地图上的摆放位子只能在平地('P') 炮兵可以攻击上下左右各两格的格子: 而高原('H')上炮兵能 ...
- poj2411 Mondriaan's Dream (轮廓线dp、状压dp)
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17203 Accepted: 991 ...
- dp,状压dp等 一些总结
也就作业几题而已,分析一下提醒 最重要的就是,记住,没用的状态无论怎么转移最后都会是没用的状态,所以每次转移以后的有值的状态都是有用的状态. 几种思考方向: 第一种:枚举当前的状态,转移成另外一个状态 ...
- BZOJ 4042 Luogu P4757 [CERC2014]Parades (树形DP、状压DP)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4042 (Luogu) https://www.luogu.org/prob ...
- hdu4352 XHXJ's LIS (数位dp)
Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then careful ...
- hoj 2662 经典状压dp // MyFirst 状压dp
题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=2662 1.引言:用dp解决一个问题的时候很重要的一环就是状态的表示,一般来说,一个数组即可保存状态. ...
- hdu4352 XHXJ's LIS(数位DP + LIS + 状态压缩)
#define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then carefully reading the entire ...
- 【BZOJ3925】地震后的幻想乡(期望概率DP,状压DP)
题意:给定一张点数不超过10的无向连通图,每条边有一个[0,1]之间的随机权值,求最小生成树上最大边的期望值 提示:对于n个[0,1]之间的随机变量x1,x2,...,xn,第k小的那个的期望值是k/ ...
随机推荐
- HTTPS SSL TLS 相关理解
1,在理解 HTTPS SSL TLS 之前先对常用的加密方式进行一个简述: (1),对称加密: 采用一个密钥,对明文进行加密生成密文,相反采用此密钥可对加密后的密文进行解密还原成明文. 代表算法有, ...
- SSM到Spring Boot入门与综合实战
一:Spring从入门到进阶 1 Spring入门 1.1 Spring IOC的底层实现原理:工厂 + 反射 + 配置文件 <bean id="us" class=&quo ...
- Leetcode之广度优先搜索(BFS)专题-1162. 地图分析(As Far from Land as Possible)
Leetcode之广度优先搜索(BFS)专题-1162. 地图分析(As Far from Land as Possible) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. ...
- pandas 分组统计
# coding:utf-8 import pandas as pd import numpy as np # path = r'C:\Users\wuzaipei\Desktop\桂林三金项目签到情 ...
- NoSQL--couchdb
Couchdb CouchDB是Apache组织发布的一款开源的.面向文档类型的NoSQL数据库.由Erlang编写,使用json格式保存数据.CouchDB以RESTful的格式提供服务可以很方便的 ...
- kafka服务器批量copy文件脚本
#!/bin/bashif [[ $# -lt 1 ]] ; then echo no params ; exit ; fiparams=$@for (( i=1 ; i <= 3 ; i = ...
- 集合运算 - Java实现集合的交、并、差
1.使用java的Set实现集合的交.并.差 package com.lfy.Set; import java.util.HashSet; import java.util.Set; /** * 集合 ...
- windows下命令行利器---Cmder(安装,中文乱码,配置右键菜单)
很多人都是在win下开发的,这样就会出现,经常需要命令行操作,而win cmd命令和linux命令有很大差异,导致大家很难受,今天给大家介绍一个win下命令行的利器-Cmder 一.先看一下它的容颜 ...
- 在 sys.servers 中找不到服务器 '10.0.2.13'。请验证指定的服务器名称是否正确。
工作中,因为需要,搭建同事的程序模块,附加了从同事那里拷过来的该程序使用的库.(C#.C/S..Net Framework4.0 .WCF.Win10.SQL Server 2014.VS2015) ...
- python并发编程-进程池线程池-协程-I/O模型-04
目录 进程池线程池的使用***** 进程池/线程池的创建和提交回调 验证复用池子里的线程或进程 异步回调机制 通过闭包给回调函数添加额外参数(扩展) 协程*** 概念回顾(协程这里再理一下) 如何实现 ...