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 ...
随机推荐
- Object类的equals方法 常用API
boolean equals (Object obj)(return this==obj): p1.equals(p2): 基本数据类型比较的是值 引用数据类型:默认比较的是两个对象的地址 ...
- Java反射:Web学习的灵魂
反射:Web学习的灵魂 我们从最初的 javac -HelloWorld.java,到面向对象部分,我们可以将Java代码在计算机中经历的阶段分为三部分:Scource源代码阶段 -- Class类对 ...
- selenium+java+testNG+maven环境搭建
一.简单介绍 1.selenium: Selenium是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE.Mozilla Fir ...
- go的命令行参数
package main import ( "fmt" "os" ) func main() { var s, sep string for i := 1; i ...
- 第七章 ZYNQ-MIZ701 GPIO使用之EMIO
7.0难度系数★☆☆☆☆☆☆ 7.1硬件截图 7.1.1 PCB上的位置 7.1.1 PCB上的位置 7.2电路分析 本次实验用到的是LD_A0~LD_A3,管脚定义如下表所示. LD_A0:F17 ...
- 【转】Entity Framework 6 Code First 实践系列(1):实体类配置-根据依赖配置关系和关联
本文转自:http://www.cnblogs.com/easygame/p/3622893.html EF实体类的配置可以使用数据注释或Fluent API两种方式配置,Fluent API配置的关 ...
- JAVA对存储过程的调用方法(本文源于网络)
博客分类: java java存储过程sql 一:Java如何实现对存储过程的调用: A:不带输出参数的 ---------------不带输出参数的-------------------- ...
- IoC(Inversion of Control 控制反转)
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中最常见的方式叫做依赖注入(Dependency Inject ...
- 怎样安装并编译TypeScript?
1. 使用: npm -v 查看是否安装了 npm , 如果没有安装, 请前往 Nodejs 官网 下载安装, 下图表示已经安装 npm , 版本为: 6.9.0 . PS C:\Users\Adm ...
- hdu 2821 学习一点dfs的小技巧吧。。 还是自己太弱了
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int r,c ...