题目链接:http://hihocoder.com/problemset/problem/1622?sid=1230113

#1622 : 有趣的子区间

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

如果一个区间[a, b]内恰好包含偶数个回文整数,我们就称[a, b]是有趣的区间。

例如[9, 12]包含两个回文整数9和11,所以[9, 12]是有趣的区间。[12, 20]包含0个回文整数,所以[12, 20]也是有趣的。

现在给定一个区间[a, b],请你求出[a, b]中所有满足a ≤ p ≤ q ≤ b的子区间[p, q]有多少个有趣的。

输入

第一行包含两个整数a和b。

对于30%的数据,1 ≤ a ≤ b ≤ 1000

对于60%的数据,1 ≤ a ≤ b ≤ 100000

对于100%的数据, 1 ≤ a ≤ b ≤ 1000000000

输出

有趣的子区间数目

样例输入
10 20
样例输出
46

菜ji题解,大牛请略过。。。

刚看到题目是半点思路也没有啊,要统计所有区间(10^9)^2,还要计算区间内回文数的个数。这。。玩不了。(手动捂脸。。

但是仔细一想特么即便区间大小长达1e9,但是1e9内的回文数不多啊(因为前一半确定了,后一半也就确定了= = ),估算一下差不多在1e5个回文数左右。。于是很顺理成章的预处理1e9内的所有回文数并排序。。。(但是有什么用呢= =)

如果每两个回文数看成一个区间,计算有趣区间个数。比如a, b, c, d, e五个回文数(从小到大),那么考虑左端点在(a, b]、右端点在(c, d]的所有区间都是有趣的,这样的计算复杂度是O(1)的。[有趣区间数=(b - a) * (d - c)],这样只要枚举回文数个数为偶数的所有回文数区间

比如加入上述例子中区间为[l, r] 且 l < a, r > e, 那么枚举有趣的区间的:

1.左端点在[l, a],右端点在[b, c)             // 区间内有两个回文数

2.左端点在[l, a],右端点在[d, e)             // 区间内有四个回文数

3.左端点在(a, b],右端点在[c, d)           // ...

4.左端点在(a, b],右端点在[e, r]           // ...

5.左端点在(b, c],右端点在[d, e)           // ...

...

对于每个枚举都是保证区间内回文数为偶数的前提下,计算左端点可取的个数x(比如样例1:x=a - l + 1), 右端点可取的个数y(比如样例1:y=c - b),那么此次枚举的有趣的区间数为x * y。最后对所有的x * y求和(即上面的枚举情况1.2.3.4.5....所有的x * y求和)即可。可以看到这样的复杂度为O(1e5 ^ 2)=O(1e10),复杂度减少了不少,但是还是接受不了啊= =

还要优化。。。

那。。继续来。。。

相信细心的读者已经注意到了,在上面的例子中情况2和情况5枚举了同一个右边界的情况[d, e),原因在于他们的左边界[l, a]和(b, c]这两个区间之间始终差距两个(偶数个)回文数,而情况1中右边界为[b,c),与情况5的左边界一致,那么在计算情况1、2、5时,便可以统一处理:

首先计算区间[b, c)和区间[d, e)的长度和(差距为偶数的区间长度和):

sum = (c - b) + (e - d) // + (g - f) + ...

那么情况1和情况2可以合并为

ans += (a - l + 1) * sum (其实这个代表所有有趣的区间的左端点落在[l, a]的方法)

在计算情况5时:

首先令sum -= c - b

ans += (c - b) * sum(其实这个代表所有有趣的区间的左端点落在(b, c]的方法)

好啦,复杂度顺利降到了O(1e5)

至于代码什么的,我的一向可读性不高啦。。有了思路应该都可以搞得定~(只是大神分分钟,蒟蒻我花了一整晚T_T)

顺便说一句,我的代码思路是[l, r]所有区间数减去非有趣的区间数计算的,因为不要忘了一个回文数没有的区间也是有趣的区间,也就是上面的左右端点都在[l, a)的区间也是有趣的。

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std; typedef long long LL; const int N = ;
const int M = ; int hwNums[N], cntHW; int rever(int n)
{
int ans = ;
while(n)
{
ans = ans * + n % ;
n /= ;
}
return ans;
} int getLenP(int n)
{
int ans = ;
while(n) ans *= , n /= ;
return ans;
} void init()
{
for(int i = ; i < ; i ++)
{
if(i < ) hwNums[cntHW ++] = i; int r = rever(i), p = getLenP(i);
hwNums[cntHW ++] = i * p + r; for (int j = ; j < ; j ++)
{
LL num = (LL)i * * p + j * p + r;
if(num <= M) hwNums[cntHW ++] = num;
}
}
// 随意添加两个更大的数,可以略去后面的边界情况讨论
hwNums[cntHW ++] = ;
hwNums[cntHW ++] = ;
sort(hwNums, hwNums + cntHW);
} // 对于l, hw1, hw2, hw3, ..., r
// 计算有趣的区间的左端点落在[l, hw1], (hw2, hw3], (hw4, hw5] ... 的所有的方法数
LL count_ans(int l, int r)
{
int id = , tid;
while(hwNums[id] <= l) id ++; // while中略去了id < cntHW,因为上面添加了两个超出边界的数
if(hwNums[id] > r) return ;
tid = id; LL sum = , pre = hwNums[id ++];
while(hwNums[id] <= r)
{
sum += hwNums[id] - pre;
pre = hwNums[++ id];
id ++;
}
if(pre <= r) sum += r + - pre; LL ans = ;
pre = l;
while(hwNums[tid] <= r)
{
ans += (hwNums[tid] - pre) * sum;
sum -= hwNums[tid + ] - hwNums[tid];
pre = hwNums[++tid];
tid ++;
}
return ans;
} int main()
{
//freopen("in.txt", "r", stdin); init(); int a, b;
cin >> a >> b;
a --; LL n = b - a, ans = n * (n + ) / ; int id = ;
while(hwNums[id] <= a) id ++; ans -= count_ans(a, b) + count_ans(hwNums[id], b); cout << ans << endl; return ;
}

hiho1622 有趣的子区间(YY)的更多相关文章

  1. HihoCoder1622 : 有趣的子区间(预处理+组合数)

    有趣的子区间 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 如果一个区间[a, b]内恰好包含偶数个回文整数,我们就称[a, b]是有趣的区间. 例如[9, 12]包含 ...

  2. [Offer收割]编程练习赛34

    共同富裕 显然每次选最大的数字,其余的加一.也可以理解为每次选一个最大的数字减一,直到所有数字都变成最小的数字为止. #include<stdio.h> #include<strin ...

  3. 我YY的一个移动应用运营模式

    尽管自己也还是刚刚毕业不久的前端新人,但网上也不乏一些案例告诉我们有志不在年高,很多优秀的同龄人已经有了不错的成就,所以在切页面写onclick之余也在进行一些思考,前端程序员的出路到底在哪里? 一. ...

  4. 洛谷 P2022 有趣的数 解题报告

    P2022 有趣的数 题目描述 让我们来考虑1到N的正整数集合.让我们把集合中的元素按照字典序排列,例如当N=11时,其顺序应该为:1,10,11,2,3,4,5,6,7,8,9. 定义K在N个数中的 ...

  5. 谈谈一些有趣的CSS题目(十二)-- 你该知道的字体 font-family

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  6. 谈谈一些有趣的CSS题目(十一)-- reset.css 知多少?

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  7. 几个有趣的WEB设备API(二)

    浏览器和设备之间还有很多有趣的接口, 1.屏幕朝向接口 浏览器有两种方法来监听屏幕朝向,看是横屏还是竖屏. (1)使用css媒体查询的方法 /* 竖屏 */ @media screen and (or ...

  8. 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  9. 谈谈一些有趣的CSS题目(一)-- 左边竖条的实现方法

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

随机推荐

  1. python-day8-列表的内置方法

    # l=[1,2,3] #l=list([1,2,3])# print(type(l)) #pat1===>优先掌握部分# 索引## 切片l=['a','b','c','d','e','f'] ...

  2. HDU-3631 Shortest Path (floyd)

    Description When YY was a boy and LMY was a girl, they trained for NOI (National Olympiad in Informa ...

  3. 通过SVN获取变更列表,得到对应的最新class

    通过本地SVN获得未提交的文件列表获取工程中最新的class的方式参考: 增量部署代码利用批处理命令按原始结构复制指定的文件 新写了一个增强版,根据已提交至SVN的代码loglist,获取最新的cla ...

  4. ps -ef |grep xxx 输出的具体含义

    ps:将某个进程显示出来 -A 显示所有程序. -e 此参数的效果和指定"A"参数相同. -f 显示UID,PPIP,C与STIME栏位. grep命令是查找 中间的|是管道命令 ...

  5. Sublime text3配置xdebug调试记录

    第一次配置遇到的问题记录: 问题:配置php.ini的时候xdebug.remote_port = 9001刚开始我一直配置9000端口冲突,然后一切弄好了访问浏览器就一直在转圈无法访问: 现在开始配 ...

  6. 自定义div 拖动。键盘上下左右键移动,ctrl+Q控制是否可以移动,ctrl+回车,返回初始状态

    <!doctype html> <html> <head> <meta charset="utf-8"> <meta name ...

  7. 申请和使用github共享代码

    1.申请github帐号 https://github.com/join?source=header-home 2.创建项目 2.1 或者: 2.2 输入信息 2.3创建成功,地址及基本命令提示 3. ...

  8. static 关键字介绍

    大家都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立.然而在某些时候,我们更希望该类所有的对象共享同一个成员.此时就是 static 大显身手的时候了!! Java 中 ...

  9. jquery的ajax post 方法传值到后台,无法通过HttpServletRequest得到

    今天通过$.ajax({type:"post"});和$.post()方法传值到后台,发现servelet通过HttpServletRequest无法获取到值,但通过get方法却可 ...

  10. 基于jquery,bootstrap数据验证插件bootstrapValidator 教程

    bootstrap:能够增加兼容性的强大框架. 因为项目需要数据验证,看bootstrapValidator 还不错,就上手一直,完美兼容,话不多说. 需要引用css: bootstrap.min.c ...