题意

自己看

分析

其实统计出现次数与出现在矩阵的那个位置无关.所以我们定义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算方案)的更多相关文章

  1. 蓝桥杯:最大的算式(爆搜 || DP)

    http://lx.lanqiao.cn/problem.page?gpid=T294 题意:中文题意. 思路:1.一开始想的是,乘号就相当于隔板,把隔板插入到序列当中,同一个隔板的就是使用加法运算, ...

  2. 铺砖头问题(完美)——爆搜&&插头DP

    题意 给定一个 $n \times m$ 的格子,每个格子被染成了黑色或白色.现在要用 $1 \times 2$ 的砖块覆盖这些格子,要求块与块之间互不重叠,且覆盖了所有白色的格子,但不覆盖任意黑色格 ...

  3. BZOJ 1207: [HNOI2004]打鼹鼠【妥妥的n^2爆搜,dp】

    1207: [HNOI2004]打鼹鼠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3259  Solved: 1564[Submit][Statu ...

  4. 【BZOJ-1853&2393】幸运数字&Cirno的完美算数教室 容斥原理 + 爆搜 + 剪枝

    1853: [Scoi2010]幸运数字 Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 1817  Solved: 665[Submit][Status] ...

  5. POJ 1166 The Clocks (爆搜 || 高斯消元)

    题目链接 题意: 输入提供9个钟表的位置(钟表的位置只能是0点.3点.6点.9点,分别用0.1.2.3)表示.而题目又提供了9的步骤表示可以用来调正钟的位置,例如1 ABDE表示此步可以在第一.二.四 ...

  6. 【 POJ - 1204 Word Puzzles】(Trie+爆搜|AC自动机)

    Word Puzzles Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 10782 Accepted: 4076 Special ...

  7. hdu5323 Solve this interesting problem(爆搜)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Solve this interesting problem Time Limit ...

  8. hdu4536-XCOM Enemy Unknown(爆搜)

    XCOM-Enemy Unknown是一款很好玩很经典的策略游戏. 在游戏中,由于未知的敌人--外星人入侵,你团结了世界各大国家进行抵抗.随着游戏进展,会有很多的外星人进攻事件.每次进攻外星人会选择3 ...

  9. poj1077 Eight【爆搜+Hash(脸题-_-b)】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4298840.html   ---by 墨染之樱花 题目链接:http://poj.org/pr ...

随机推荐

  1. Jquery对表单、表格的操作以及应用

    表单的应用 (1)表单标签:包含处理表单数据所用的服务器端程序URL以及数据提交到服务器的方法 (2)表单域:包含文本框.密码框.隐藏域.多行文本框.复选框.单选框.下拉选择框.和文件上传框 (3)表 ...

  2. 把Javascript 对象转换为键值对连接符字符串的方法总结

    307down votefavorite 93 Do you know a fast and simple way to encode a Javascript Object into a strin ...

  3. java类和对象详解

    类和对象 java 是面向对象的语言 即 万物皆对象c语言是面向过程语言 一.怎么去描述一个对象? (1)..静态的(短时间内不会改变的东西) 例如:外观,颜色,品牌 (2).动态的(动作) 可以干什 ...

  4. SQLite进阶-18.事务

    目录 SQLite事务 事务的属性 事务控制 BEGIN TRANSACTION命令 COMMIT命令 ROLLBACK命令 SQLite事务 事务(Transaction) 是一个对数据库执行工作单 ...

  5. 在linux下进行数据备份

    一.完全备份 完全备份是指把所有需要备份的数据全部备份.当然,完全备份可以备份整块硬盘.整个分区或某个具体的目录.完全备份的好处是数据恢复方便,因为所有的数据都在同一个备份中,所以只要恢复完全备份,所 ...

  6. thinkphp5.1路由设置小计

    route下定义路由路径,如果是这种情况 'product'=>'home/product/index',//产品信息首页 'product/list'=>'home/product/li ...

  7. js图片压缩上传

    最近公司的移动产品相约app要做一次活动,涉及到图片上传,图片又不能太大,不然用户体验太差,必须先压缩再上传,所以用到了html5的canvas和FileReader,代码先上,小弟前端经验不足,代码 ...

  8. go的命令行参数

    package main import ( "fmt" "os" ) func main() { var s, sep string for i := 1; i ...

  9. 常用javascript内置对象——String对象

    创建 String 对象的语法: 1:new String(s); :2:String(s); :3:直接赋值 String中属性 String中方法 <script> window.on ...

  10. VBA精彩代码分享-2

    VBA开发中经常需要提示消息框,如果不关闭程序就会暂时中断,这里分享下VBA如何实现消息框的自动关闭,总共有三种方法: 第一种方法 Public Declare Function MsgBoxTime ...