打表出奇迹!表打出来发现了神奇的规律:

1 1 2 2 3 4 4 4 5 6 6 7 8 8 8 8 9 10 10 11 12 12 12 13 14 14 15 16 16 16 16 16...

嗯嗯嗯?没有规律?我们把每个数出现的次数列出来:

2 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5

然后惊觉表中的数字是连续的,每个都至少有一个,而分解因数中有只要2的幂,有一个就会加一,比如8是2、4、8的倍数,在1的基础上会多三个。(1和2除外)

所以对于一个位置$x$,我们可以二分出它的值前面那个值,check的时候计算二分的值总共占了多少位置即可。而求和时又发现,基数是一段连续的等差数列,之后每次都是累加2的幂的等差数列。把前面的值计算完后,把$x$代表的值的个数加起来即可。这样就可以用前缀和相减得出答案了。

注意取模的位置,好事多模!

#include<iostream>
#include<cstdio>
#define LL long long
#define mod 1000000007
using namespace std; LL vi = ; LL count ( LL mid ) {
LL k = , num = ;
while ( k <= mid ) {
num += mid / k;
if ( num > 1e18 ) break;
k *= ;
}
return num + ;//2个1
} LL work ( LL x ) {
if ( x == ) return ;
if ( x == ) return ;
if ( x == ) return ;
LL l = , r = x, pos, sum;
while ( l <= r ) {
LL mid = ( l + r ) >> ;
LL tmp = count ( mid );
if ( tmp < x ) l = mid + , pos = mid, sum = tmp;
else r = mid - ;
}
LL ans = , k = ;
while ( k <= pos ) {
ans = ( ans + ( k + pos / k * k % mod ) % mod * ( pos / k % mod ) % mod * vi % mod ) % mod;
k *= ;
}
LL res = ( ( ( x - sum ) % mod ) + mod ) % mod;
ans = ( ans + res * ( pos + ) % mod ) % mod;
return ans;
} int main ( ) {
freopen ( "me.in", "r", stdin );
freopen ( "me.out", "w", stdout );
LL L, R;
cin >> L >> R;
cout << ( ( work ( R ) - work ( L - ) ) % mod + mod ) % mod << endl;
return ;
}

这个模数真是...看到觉得是$FFT$凉了啊...

结果就是个二维DP!而且题目上$x$给的虽然是10000,但是$n$是80,实际的$x$想上300都难!

定义$dp[i][k]$表示当前从前往后填到了$i$,我们只当当前区间长度是$i$。$k$表示当前贡献。枚举填$i$的位置$j$由于$1-j-1$已经统计出方案数,而相对大小是不会因为新加的数改变的,前面填的方案数就是$C(i-1,j-1)$。所以枚举前后段的贡献,用乘法原理更新答案即可。

#include<iostream>
#include<cstdio>
#define LL long long
#define MOD 998244353
using namespace std; LL dp[][], M[], C[][]; int n, x; void Work ( ) {
for ( int i = ; i <= n; i ++ )
for ( int j = ; j <= i; j ++ )
if ( i == j || j == || i == ) C[i][j] = ;
else C[i][j] = ( C[i-][j-] + C[i-][j] ) % MOD;
dp[][] = dp[][] = ;
M[] = ;
for ( int i = ; i <= n; i ++ )//从小到大插入数
for ( int j = ; j <= i; j ++ ) {//枚举插入位置 (有相对大小即可,不需要准确位置,当前区间长度为i
int r = min ( j, i - j + ), tmp = C[i-][j-];//r是当前插入的数提供的贡献
M[i] = max ( M[i], M[j-] + M[i-j] + r );//i个数放入达到的最大贡献
for ( int k1 = j-; k1 <= M[j-]; k1 ++ )
for ( int k2 = i-j; k2 <= M[i-j]; k2 ++ )
dp[i][r+k1+k2] = ( dp[i][r+k1+k2] + dp[j-][k1] * dp[i-j][k2] % MOD * tmp % MOD ) % MOD;
}
if ( n > x || x > M[n] ) printf ( "" );
else printf ( "%I64d", dp[n][x] );
} int main ( ) {
freopen ( "good.in", "r", stdin );
freopen ( "good.out", "w", stdout );
scanf ( "%d%d", &n, &x );
Work ( );
return ;
}

题目改成了可不可以达到,输出1和-1。

很容易想到和背包有关。可是$x$的数据范围??

但是看到$A$的范围??可以想到恰好装满$x$实际上可以转换为用$A_2-A_n$装满$x%A_1$(装的过程也对$A_1$取模),所以空间一下子就压到了$1e5$叻!

可是还有一种情况:比如$A$是4、6、8,$x$是2,按照刚才的算法这样也是算可以,把6单独拿出来%4就是2。这意味着我们必须要判断背包过程中达到$x%A_1$可行的最小方案必须要小于等于$x$。所以可以跑$Spfa$边更新可行边记录最小方案。

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define RG register
#define LL long long
using namespace std; int n, Q;
LL dis[];
int vis[], a[];
queue < LL > q;
void Spfa ( ) {
memset ( dis, -, sizeof ( dis ) );
dis[] = ; q.push ( ); vis[] = ;
while ( !q.empty ( ) ) {
LL x = q.front ( ); q.pop ( ); vis[x] = ;
for ( RG int i = ; i <= n; i ++ ) {
LL v = ( x + a[i] ) % a[];
if ( dis[v] < || dis[v] > dis[x] + a[i] ) {
dis[v] = dis[x] + a[i];
if ( !vis[v] ) {
vis[v] = ;
q.push ( v );
}
}
}
}
} int main ( ) {
freopen ( "hungry.in", "r", stdin );
freopen ( "hungry.out", "w", stdout );
scanf ( "%d%d", &n, &Q );
for ( RG int i = ; i <= n; i ++ ) scanf ( "%d", &a[i] );
Spfa ( );
while ( Q -- ) {
LL x;
scanf ( "%I64d", &x );
if ( dis[x % a[]] < || dis[x % a[]] > x ) printf ( "-1\n" );
else printf ( "1\n" );
}
return ;
}

【8.31校内测试】【找规律二分】【DP】【背包+spfa】的更多相关文章

  1. 找规律/数位DP HDOJ 4722 Good Numbers

    题目传送门 /* 找规律/数位DP:我做的时候差一点做出来了,只是不知道最后的 is_one () http://www.cnblogs.com/crazyapple/p/3315436.html 数 ...

  2. 【10.31校内测试】【组合数学】【记忆化搜索/DP】【多起点多终点二进制拆位Spfa】

    Solution 注意取模!!! Code #include<bits/stdc++.h> #define mod 1000000007 #define LL long long usin ...

  3. 【9.7校内测试】【二分+spfa】【最长上升子序列】【状压DP+贪心(?)】

    刘汝佳蓝书上的题,标程做法是从终点倒着$spfa$,我是二分答案正着$spfa$判断可不可行.效果是一样的. [注意]多组数据建边一定要清零啊QAQ!!! #include<iostream&g ...

  4. 2017年icpc西安网络赛 Maximum Flow (找规律+数位dp)

    题目 https://nanti.jisuanke.com/t/17118 题意 有n个点0,1,2...n-1,对于一个点对(i,j)满足i<j,那么连一条边,边权为i xor j,求0到n- ...

  5. Codeforces D. Little Elephant and Interval(思维找规律数位dp)

    题目描述: Little Elephant and Interval time limit per test 2 seconds memory limit per test 256 megabytes ...

  6. 【春训团队赛第四场】补题 | MST上倍增 | LCA | DAG上最长路 | 思维 | 素数筛 | 找规律 | 计几 | 背包 | 并查集

    春训团队赛第四场 ID A B C D E F G H I J K L M AC O O O O O O O O O 补题 ? ? O O 传送门 题目链接(CF Gym102021) 题解链接(pd ...

  7. Codeforces Round #260 (Div. 2) A , B , C 标记,找规律 , dp

    A. Laptops time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  8. 【10.4校内测试】【轮廓线DP】【中国剩余定理】【Trie树+博弈】

    考场上几乎是一看就看出来轮廓线叻...可是调了两个小时打死也过不了手出样例!std发下来一对,特判对的啊,转移对的啊,$dp$数组竟然没有取max!!! 某位考生当场死亡. 结果下午又请了诸位dala ...

  9. 【8.28校内测试】【区间DP】

    感受到了生活的艰辛QAQ...这才是真正的爆锤啊...(因为t1t3还没有理解所以只能贴t2叻QAQ 区间DP...爆哭把题理解错了,以为随着拿的东西越来越多,断点也会越来越多,出现可以选很多的情况Q ...

随机推荐

  1. thinkphp 漂亮的分页样式

    ---恢复内容开始--- 首先:需要两个文件 page.class.php page.css 1.在TP原有的 page.class.php 文件稍作修改几条代码就可以了, 修改过的地方我会注释, 2 ...

  2. React 16 源码瞎几把解读 【二】 react组件的解析过程

    一.一个真正的react组件编译后长啥样? 我们瞎几把解读了react 虚拟dom对象是怎么生成的,生成了一个什么样的解构.一个react组件不光由若干个这些嵌套的虚拟dom对象组成,还包括各种生命周 ...

  3. fprintf输出到文件中,sprintf输出到字符串中. 如: fprintf(fp,"%s",name); fp为文件指针 sprintf(buff,"%s",name); buff为字符数组

    fprintf输出到文件中,sprintf输出到字符串中. 如: fprintf(fp,"%s",name); fp为文件指针 sprintf(buff,"%s" ...

  4. redis关闭保护模式

    1. set key出现的报错 在192.168.56.57客户端登录192.168.56.56的redis服务器时,报错如下: [root@localhost src]# ./redis-cli - ...

  5. wordpress技术-禁止订阅用户访问后台

    begin主题虽然有个功能,但是只是少了入口,实际上测试还是可以进入后台的,那么怎么彻底解决呢?一时半会没思路,百度了下,果然有人贴出了代码. 把下面代码黏贴到主题的模板函数文件里即可: if ( i ...

  6. IEEEXtreme 10.0 - Flower Games

    这是 meelo 原创的 IEEEXtreme极限编程比赛题解 题目来源 第10届IEEE极限编程大赛 https://www.hackerrank.com/contests/ieeextreme-c ...

  7. list列表常用方法

    列表是Python中常用的功能,我们知道,列表可以用来存储很多信息,掌握列表的功能有助于我们处理更多的问题,下面来看看列表都具有那些属性:     1.append(self,p_object) de ...

  8. pip/conda国内镜像--安装包提速

    对于Python开发用户来讲,PIP安装软件包是家常便饭.但国外的源下载速度实在太慢,浪费时间.而且经常出现下载后安装出错问题.所以把PIP安装源替换成国内镜像,可以大幅提升下载速度,还可以提高安装成 ...

  9. Python 的十个自然语言处理工具

    原文 先mark,后续尝试. 1.NLTK NLTK 在用 Python 处理自然语言的工具中处于领先的地位.它提供了 WordNet 这种方便处理词汇资源的借口,还有分类.分词.除茎.标注.语法分析 ...

  10. 浅谈BUFF设计

    Buff在游戏中无处不在,比如WOW.DOTA.LOL等等,这些精心设计的BUFF,让我们击节赞叹,沉迷其中. 问:BUFF的本质是什么? BUFF 是对一项或多项数据进行瞬间或持续作用的集合.(持续 ...