题目链接: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. 读写生信流程必备的 Perl 语法

    最早就是写Perl的,后来来到公司转Python,现在又要负责流程了,开始重拾Perl,当然是借鉴别人现有的语法,我再重新组合. 基本语法就不介绍了,参照我之前文章 Perl   模块 use str ...

  2. 51 jquery 节点操作和 bootstrapt

    jquery 和 bootstrapt1.jquery each 函数 1.each 循环方式一: 可循环对象: var arr =["alex","deng" ...

  3. 秒杀多线程第五篇 经典线程同步 关键段CS

    本文首先介绍下如何使用关键段,然后再深层次的分析下关键段的实现机制与原理. 关键段CRITICAL_SECTION一共就四个函数,使用很是方便.下面是这四个函数的原型和使用说明. 函数功能:初始化 函 ...

  4. 在oaf中集成SpringLoaded实现热部署

    首先声明:其实JRebel和Spring-Loaded就是一个开发环境下的利器,skip build and redeploy process,大大提升了工作效率!而非生产环境的利器... 不要在生产 ...

  5. 43. Multiply Strings 字符串表示的大数乘法

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  6. iOS UI-微博案例(通过代码自定义Cell)

    一.Model BWWeiBo数据模型 #import <Foundation/Foundation.h> @interface BWWeiBo : NSObject @property ...

  7. C++技能重拾

    0.虽然静态成员函数不存在this指针,但还是不能在一个class里声明同名同参的虚函数和静态成员函数. 1.vftable里一个虚函数表是一个指针 2.delete本质,调用析构函数同时释放内存Ob ...

  8. c#输出指定信息到文本文件中(追加方式)

    /// <summary> /// 输出指定信息到文本文件 /// </summary> /// <param name="msg">输出信息& ...

  9. 快速切题 sgu119. Magic Pairs

    119. Magic Pairs time limit per test: 0.5 sec. memory limit per test: 4096 KB “Prove that for any in ...

  10. sgu114. Telecasting station 难度:1

    114. Telecasting station time limit per test: 0.25 sec. memory limit per test: 4096 KB Every city in ...