51nod 1989 竞赛表格 (爆搜+DP算方案)
题意
分析
其实统计出现次数与出现在矩阵的那个位置无关.所以我们定义f(i)f(i)f(i)表示iii的出现次数.那么就有转移方程式f(i)=1+∑j+rev(j)=if(j)f(i)=1+\sum_{j+rev(j)=i}f(j)f(i)=1+j+rev(j)=i∑f(j)但是这样的话jjj可以取的值太多了,无法DP,怎么办呢?题解给出了巧妙的优化.我们只考虑那些形如"x+rev(x)x+rev(x)x+rev(x)“的jjj来转移,那么剩下的不形如”x+rev(x)x+rev(x)x+rev(x)“的数一定在矩阵中只出现了一次.定义形如”x+rev(x)x+rev(x)x+rev(x)"的并集为SSS.那么转移就可以写成:
f(i)−1=∑j+rev(j)=if(j)=∑j+rev(j)=i,j⊂Sf(j) +∑j+rev(j)=i,j⊄S1=∑j+rev(j)=i,j⊂S(f(j)−1) +∑j+rev(j)=i1\begin{aligned}f(i)-1&=\sum_{j+rev(j)=i}f(j)\\&=\sum_{j+rev(j)=i,j\sub S}f(j)\ \ + \sum_{j+rev(j)=i,j\sub\not S}1\\&=\sum_{j+rev(j)=i,j\sub S}\left(f(j)-1\right)\ \ + \sum_{j+rev(j)=i}1\end{aligned}f(i)−1=j+rev(j)=i∑f(j)=j+rev(j)=i,j⊂S∑f(j) +j+rev(j)=i,j⊄S∑1=j+rev(j)=i,j⊂S∑(f(j)−1) +j+rev(j)=i∑1
那么转移数就等于状态数了,然而搜出来可以发现,在[1,1010][1,10^{10}][1,1010]内SSS的元素大约是254119625411962541196个,所以我们只需要爆搜预处理然后DP就行了,+号右边的部分是可以在爆搜过程中处理出来的.最后求一个fff的前缀和,那么对于[L,R][L,R][L,R]区间内的数总出现次数就是f(upper_bound(R)−1)−f(upper_bound(L−1)−1)+(R−L+1)f(upper\_bound(R)-1)-f(upper\_bound(L-1)-1)+(R-L+1)f(upper_bound(R)−1)−f(upper_bound(L−1)−1)+(R−L+1).这里的upper_bound−1upper\_bound-1upper_bound−1表示找到数组中小于等于当前值的最靠后的下标.
那到底怎么爆搜呢?要找形如x+rev(x)x+rev(x)x+rev(x)的数,首先枚举xxx的位数分别搜索.举个栗子,x位数为5.设x=abcde‾(a>0)x=\overline{abcde}(a>0)x=abcde(a>0).所以x+rev(x)=(a+e)(b+d)(c+c)(b+d)(a+e)‾x+rev(x)=\overline{(a+e)(b+d)(c+c)(b+d)(a+e)}x+rev(x)=(a+e)(b+d)(c+c)(b+d)(a+e).当然这是要进位的,为了方便不写了.两个位数加起来值域是[0,18][0,18][0,18],那么我们只需要枚举这个和爆搜,然后顺便算一下方案就行了.这样爆搜可能有相同的数,把相同的数分开存也只有254125825412582541258个,所以搜出来排序去重就行了,注意去重要把方案数加起来.
CODE
#include <map>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
template<typename T>inline void read(T &num) {
char ch; while((ch=getchar())<'0'||ch>'9');
for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
}
const int MAXN = 2600005;
int cur, tot, id[MAXN];
LL num[MAXN], g[MAXN], arr[MAXN], sum[MAXN], mul[11];
LL rev(LL x) {
LL res = 0;
while(x) res = res*10 + x%10, x /= 10;
return res;
}
void ser(int i, int len, LL x, LL ways) { //way表示到当前的方案数
if(x > mul[10]) return;
if(i == (len+1)>>1) {
num[++cur] = x; id[cur] = cur; g[cur] = ways; return;
}
if(!i) {
if(i == len-i-1)
for(int digit = 1; digit <= 9; ++digit)
ser(i+1, len, x+digit*mul[i]*2, ways);
else
for(int digit = 1; digit <= 18; ++digit)
ser(i+1, len, x+digit*(mul[i]+mul[len-i-1]), ways*(digit<=9?digit:9-(digit-10)));
}
else {
if(i == len-i-1)
for(int digit = 0; digit <= 9; ++digit)
ser(i+1, len, x+digit*mul[i]*2, ways);
else
for(int digit = 0; digit <= 18; ++digit)
ser(i+1, len, x+digit*(mul[i]+mul[len-i-1]), ways*(digit<=9?digit+1:9-(digit-10)));
}
}
inline bool cmp(const int &i, const int &j) { return num[i] < num[j]; }
int main () {
mul[0] = 1; for(int i = 1; i <= 10; ++i) mul[i] = mul[i-1] * 10;
for(int len = 1; len <= 10; ++len) ser(0, len, 0, 1);
sort(id+1, id+cur+1, cmp); //排序编号
for(int i = 1; i <= cur+1; ++i)
if(num[id[i]] == num[id[i-1]]) g[id[i]] += g[id[i-1]]; //可能有相同的数
else if(i > 1) arr[++tot] = num[id[i-1]], sum[tot] = g[id[i-1]];
for(int i = 1; i <= tot; ++i)
sum[lower_bound(arr+1, arr+tot+1, arr[i]+rev(arr[i]))-arr] += sum[i], sum[i] += sum[i-1]; //DP+求前缀和
int Q; LL L, R, P, ans = 0;
read(Q);
while(Q--) {
read(L), read(R), read(P);
ans ^= (sum[upper_bound(arr+1, arr+tot+1, R)-arr-1]-sum[upper_bound(arr+1, arr+tot+1, L-1)-arr-1] + R-L+1) % P;
}//O(log)询问
printf("%lld\n", ans);
}
51nod 1989 竞赛表格 (爆搜+DP算方案)的更多相关文章
- 蓝桥杯:最大的算式(爆搜 || DP)
http://lx.lanqiao.cn/problem.page?gpid=T294 题意:中文题意. 思路:1.一开始想的是,乘号就相当于隔板,把隔板插入到序列当中,同一个隔板的就是使用加法运算, ...
- 铺砖头问题(完美)——爆搜&&插头DP
题意 给定一个 $n \times m$ 的格子,每个格子被染成了黑色或白色.现在要用 $1 \times 2$ 的砖块覆盖这些格子,要求块与块之间互不重叠,且覆盖了所有白色的格子,但不覆盖任意黑色格 ...
- BZOJ 1207: [HNOI2004]打鼹鼠【妥妥的n^2爆搜,dp】
1207: [HNOI2004]打鼹鼠 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3259 Solved: 1564[Submit][Statu ...
- 【BZOJ-1853&2393】幸运数字&Cirno的完美算数教室 容斥原理 + 爆搜 + 剪枝
1853: [Scoi2010]幸运数字 Time Limit: 2 Sec Memory Limit: 64 MBSubmit: 1817 Solved: 665[Submit][Status] ...
- POJ 1166 The Clocks (爆搜 || 高斯消元)
题目链接 题意: 输入提供9个钟表的位置(钟表的位置只能是0点.3点.6点.9点,分别用0.1.2.3)表示.而题目又提供了9的步骤表示可以用来调正钟的位置,例如1 ABDE表示此步可以在第一.二.四 ...
- 【 POJ - 1204 Word Puzzles】(Trie+爆搜|AC自动机)
Word Puzzles Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 10782 Accepted: 4076 Special ...
- hdu5323 Solve this interesting problem(爆搜)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Solve this interesting problem Time Limit ...
- hdu4536-XCOM Enemy Unknown(爆搜)
XCOM-Enemy Unknown是一款很好玩很经典的策略游戏. 在游戏中,由于未知的敌人--外星人入侵,你团结了世界各大国家进行抵抗.随着游戏进展,会有很多的外星人进攻事件.每次进攻外星人会选择3 ...
- poj1077 Eight【爆搜+Hash(脸题-_-b)】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4298840.html ---by 墨染之樱花 题目链接:http://poj.org/pr ...
随机推荐
- linux系统调用、库函数和内核函数关系与区别
看系统调用,还有库函数,以前一直不明白,总是以为 系统调用跟库函数是一样的,但是今天才知道是不一样的. 库函数也就是我们通常所说的应用编程接口API,它其实就是一个函数定义,比如常见read().wr ...
- python+selenium+chrome实现自动登录百度
#python3.4+selenium3.5+chrome版本 63.0.3239.132+chrome驱动chromedriver.exe #实现自动登录百度 from selenium impor ...
- SHE姐妹建模记录
中午11点54分,队长把MD5码提交上去在群里发了截图,我对着屏幕上刚检查完的论文,感觉整个人都轻松起来了,又有点恍惚,可能是这几天都没睡好觉.去楼下吃了顿饭,本来打算回来倒头就睡,睡到几点算几点,醒 ...
- 计算机基础与python安装
计算机基础 内容详细: 一.计算机基础 1. 计算机什么组成的 输入输出设备 cpu 硬盘 内存 中央处理器 处理各种数据 相当于人的大脑 内存 存储数据 硬盘 存储数据的 2. 什么是操作系统 控制 ...
- CPA ,CFA,ACCA
CPA是“注册会计师”(Certified Public Accountant,CPA)的简称,是指取得注册会计师证书并在会计师事务所执业的人员,是从事社会审计/中介审计/独立审计的专业人士,CPA为 ...
- Path.Combine(
// 获取程序的基目录. var dir1 = System.AppDomain.CurrentDomain.BaseDirectory; // 获取模块的完整路径. var dir2 = Syste ...
- margin:0 auto;生效条件
1.position:absolute下不生效 原因:position:absolute只能相对于父元素进行定位top.left定位,相当于浮在父元素上面,所以margin:0 auto;就没有了参考 ...
- MVC和WebApi中设置Area中的页为首页
拿WebApi为例,我们一般会生成一份帮助文档,帮助文档会在Area中 我们现在要讲帮助文档设为首页 只需在App_Start文件夹下添加 RouteConfig 类 public class Rou ...
- 15 Django之Celery发送邮件
异步任务--celery发送邮件 安装两个python包: pip install celery==3.1.25 pip install django-celery==3.2.1 pip instal ...
- Python: NumPy, Pandas学习资料
NumPy 学习资料 书籍 NumPy Cookbook_[Idris2012] NumPy Beginner's Guide,3rd_[Idris2015] Python数据分析基础教程:NumPy ...