problem

loj-3144

题意概要:设函数 \(f(t)\) 的返回值为一个二元组,即 \(f(t)=((t+\lfloor \frac tB\rfloor)\bmod A, t\bmod B)\),现在给出 \(n\) 个区间,问 \(t\) 在这 \(n\) 个区间中取值时,有多少个不同的 \(f(t)\)。

\(n\leq 10^6,\ l_i,r_i,A,B\leq 10^{18}\),区间互不相交

Solution

一开始没啥想法,\(loj\) 的题面上写了 \(l_i\leq r_i,r_i<l_i+1\)……这不就是说 \(l_i=r_i\) 嘛!暴力 \(O(n)\) 就好了!

实际上是 \(r_i<l_{i+1}\),然后看着 \(5\) 分一档的部分分陷入了沉思……后来直接想正解发现正解比暴力容易……

由于不同的二元组难以考虑,考虑两个二元组相同的情况(即 \(f(t_1)=f(t_2)\))。同时这个二元组中的两个函数中,第二维较为简单,考虑从这一维下手。

由于第二维要相同,所以两个相同二元组一定是 \(f(x)\) 与 \(f(x+kB)\) 形式的,再考虑第一维:

\[x+\lfloor \frac xB\rfloor \equiv x+kB+\lfloor \frac {x+kB}B\rfloor \pmod A\\
x+\lfloor \frac xB\rfloor \equiv x+\lfloor \frac xB\rfloor +kB+k \pmod A\\
k(B+1)\equiv 0\pmod A
\]

又由于满足 \(k(B+1)\equiv 0\pmod A\) 的最小 \(k=\frac A{\gcd\{A,B+1\}}\)

即满足 \(f(x)=f(y)\) 的,一定满足 \(\frac {AB}{\gcd \{A,B+1\}}|(y-x)\)。换种说法,也即 \(x\equiv y\pmod {\frac {AB}{\gcd\{A,B+1\}}}\)。

问题转化为在模 \(\frac {AB}{\gcd\{A,B+1\}}\) 意义下的覆盖区间长度,时间复杂度 \(O(n\log n)\)。

Code

//loj-3144
#include <bits/stdc++.h>
using namespace std;
typedef long long ll; template <typename _tp> inline void read(_tp&x){
char ch=getchar();x=0;while(!isdigit(ch))ch=getchar();
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
} inline ll gcd(ll A, ll B) {return B ? gcd(B, A%B) : A;} const int N = 2001000;
typedef pair <ll,int> pli;
pli a[N];
int n, tot;
ll A, B; int main() {
read(n), read(A),read(B);
ll d = A / gcd(A, B+1);
ll l, r, l0, l1, r0, r1;
bool flg = false;
if(1e18 / B < d) {
for(int i=1;i<=n;++i) {
read(l), read(r);
a[++tot] = pli(l, +1);
a[++tot] = pli(r+1, -1);
}
flg = true;
} else {
d *= B;
for(int i=1;i<=n;++i) {
read(l), l0 = l % d, l1 = l / d;
read(r), r0 = r % d, r1 = r / d;
if(l1 == r1) {
a[++tot] = pli(l0, +1);
a[++tot] = pli(r0+1, -1);
} else if(l1 + 1 == r1) {
a[++tot] = pli(l0, +1);
a[++tot] = pli(0, +1);
a[++tot] = pli(r0+1, -1);
} else return printf("%lld\n", d), 0;
}
} if(!flg) a[++tot] = pli(d, 0);
a[0] = pli(0, 0);
sort(a+1, a+tot+1); int vl = 0;
ll Ans = 0ll;
for(int i=1;i<=tot;++i) {
if(vl) Ans += a[i].first - a[i-1].first;
vl += a[i].second;
}
printf("%lld\n", Ans);
return 0;
}

最新文章

  1. JQuery面试题答案
  2. Aster及其它遥感数据下载地址
  3. 导入word数据
  4. [leetcode] 400. Nth Digit
  5. NVelocity 实例
  6. Hive 行列转换
  7. bootstrap-datetimepicker bootstrap-datepicker bootstrap-timepicker 时间插件
  8. 在 Vim 中设置 Tab 为4个空格
  9. jQuery结合lhgdialog弹出窗口,关闭时出现没有权限错误
  10. 20175305张天钰 《java程序设计》第四周课下测试总结
  11. elasticsearch(1) 安装和使用
  12. SQL SERVER2008 数据库日志文件的收缩方法
  13. Hbase设置多个hmaster
  14. python easy_install 发生Unable to find vcvarsall.bat错误的处理方法
  15. 20145202马超《网络对抗》Exp9*_* Web安全基础实践
  16. XSS的各种用途
  17. MVC学习__修改工程端口号
  18. 所有iOS设备的屏幕分辨率
  19. springboot Tomcat connector configured to listen on port 8081 failed to start.
  20. [poj 2185] Milking Grid 解题报告(KMP+最小循环节)

热门文章

  1. 树莓派连接18b20测温度
  2. Java-Maven(十):Maven 项目常用plugins
  3. HTMLPage测试js通过ajax调用
  4. Excel 如何自动调整列宽?
  5. centos sqlite3安装及简单命令
  6. MiniDao &amp; Freemarker &amp; include
  7. idea 报错javax/xml/bind/DatatypeConverter
  8. getField和getDeclaredField的区别
  9. doris: shell invoke .sql script for doris and passing values for parameters in sql script.
  10. lnmp 多版本php 同时运行