多校hdu5726 线段树+预处理
第一问是没有修改的线段树,第二问暴力预处理,因为gcd的结果不会很多
在预处理阶段需要把每个区间的gcd相等的数量储存起来(用map容器),在一个序列例如:12467,枚举左区间L直到n此处时间为O(n),l=1时寻找右区间随着r的增大gcd单调不增,在某个区域内gcd相等想到用二分查找时间是O(logn),再加上线段树查找用到时间O(logn),总时间是O(n*logn*longn)会超时,所以需要更优。
解决办法:左区间固定时利用线段树找到gcd减小的区间,从l到gcd减小的区间gcd相等。
#include<map>
#include<stdio.h>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
const int N = 4e5 + 10;
int T, n, m, g[N], a[N], l, r, q, cas = 0;
map<int, LL> M;
int gcd(int x, int y) { return x%y ? gcd(y, x%y) : y; }
void build(int x, int l, int r)
{
if (l == r) scanf("%d", &g[x]), a[l] = g[x];
else
{
int mid = l + r >> 1;
build(x << 1, l, mid);
build(x << 1 | 1, mid + 1, r);
g[x] = gcd(g[x << 1], g[x << 1 | 1]);
}
} int get(int x, int l, int r, int ll, int rr)
{
if (ll <= l&&r <= rr) return g[x];
int mid = l + r >> 1;
int x1 = 0, x2 = 0;
if (ll <= mid) x1 = get(x << 1, l, mid, ll, rr);
if (rr > mid) x2 = get(x << 1 | 1, mid + 1, r, ll, rr);
return gcd(min(x1, x2), max(x1, x2));
} bool find(int x, int l, int r, int ll, int rr, int u, int &v)
{
if (ll <= l && r <= rr)
{
if (gcd(v, g[x]) < u)
{
if (l == r)
{
q = l; return true;
}
else
{
int mid = l + r >> 1;
if (find(x<<1, l, mid, ll, rr, u, v)) return true;
if (find(x<<1|1, mid + 1, r, ll, rr, u, v)) return true;
}
}
else { v = gcd(v, g[x]); return false; }
}
else
{
int mid = l + r >> 1;
if (ll <= mid&&find(x<<1, l, mid, ll, rr, u, v)) return true;
if (rr > mid&& find(x<<1|1, mid + 1, r, ll, rr, u, v)) return true;
return false;
}
} int main()
{
scanf("%d", &T);
while (T--)
{
M.clear();
scanf("%d", &n);
build(1, 1, n);
for (int i = 1, j, k; i <= n; i++)
{
int kk = get(1, 1, n, i, n);
for (k = i, j = a[i]; k <= n;)
{
if (kk == j) { M[j] += n - k + 1; break; }
int gg = a[i];
find(1, 1, n, i, n, j, gg);
M[j] += q - k;
k = q; j = gcd(a[q], j);
}
}
scanf("%d", &m);
printf("Case #%d:\n", ++cas);
while (m--)
{
scanf("%d%d", &l, &r);
int x = get(1, 1, n, l, r);
printf("%d %lld\n", x, M[x]);
}
}
return 0;
}
多校hdu5726 线段树+预处理的更多相关文章
- HDU 4960 Handling the past 2014 多校9 线段树
首先确定的基本思想是按时间离散化后来建线段树,对于每个操作插入到相应的时间点上 但是难就难在那个pop操作,我之前对pop操作的处理是找到离他最近的那个点删掉,但是这样对于后面的peak操作,如果时间 ...
- HDU 4893 2014多校三 线段树
给定一个初始都为0的序列,有三种操作,前两种比较正常,一个是对某个位置的数add k,另一个是query区间和.然后比较麻烦的是第三个操作,把某个区间里面的每个值改成离它最近的Fibonacci数,如 ...
- HDU 4902 Nice boat 多校4 线段树
给定n个数 第一个操作和普通,区间覆盖性的,把l-r区间的所有值改成固定的val 第二个操作是重点,输入l r x 把l-r区间的所有大于x的数,变成gcd(a[i],x) a[i]即指满足条件的序列 ...
- HDU - 4366 Successor DFS序 + 分块暴力 or 线段树维护
给定一颗树,每个节点都有忠诚和能力两个参数,随意指定一个节点,要求在它的子树中找一个节点代替它,这个节点要满足能力值大于它,而且是忠诚度最高的那个. 首先,dfs一下,处理出L[i], R[i]表示d ...
- BZOJ 3173: [Tjoi2013]最长上升子序列 (线段树+BIT)
先用线段树预处理出每个数最终的位置.然后用BIT维护最长上升子序列就行了. 用线段树O(nlogn)O(nlogn)O(nlogn)预处理就直接倒着做,每次删去对应位置的数.具体看代码 CODE #i ...
- 2016暑假多校联合---Rikka with Sequence (线段树)
2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...
- hdu(预处理+线段树)
给n个数,m个询问, 问任意区间内与其它数互质的数有多少个 比如3个数1 2 4,询问[1,3] 那么答案是1 千万要记住,这样的题目,如果你不转变下,使劲往线段树想(虽然转变之后,也说要用到线段树, ...
- [Bzoj5358][Lydsy1805月赛]口算训练(预处理+动态开点线段树)
5358: [Lydsy1805月赛]口算训练 Time Limit: 5 Sec Memory Limit: 512 MBSubmit: 318 Solved: 105[Submit][Stat ...
- BestCoder Round #29 1003 (hdu 5172) GTY's gay friends [线段树 判不同 预处理 好题]
传送门 GTY's gay friends Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Ot ...
随机推荐
- mongo-connector来同步mongo
个人博客:https://blog.sharedata.info/ 最近需要做mongo之间的同步,因此还是选择之前的工具mongo-connectorgitHub文档:https://github. ...
- Core Services层
本文转载至 http://jingyan.baidu.com/article/cdddd41c57360853cb00e124.html Core Services层是系统很多部分的基础部分,也许应用 ...
- Python数据驱动ddt
import ddtimport unittest """ddt模块包含了一个类的装饰器ddt和两个方法的装饰器: data:包含多个你想要传给测试用例的参数: file ...
- poj1676(转换为二进制求解)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=13175 题目关键:将0~9十个数转换为二进制数进行枚举比较 int ...
- 【BZOJ2730】[HNOI2012]矿场搭建 Tarjan
[BZOJ2730][HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处. ...
- 1282 时钟(最小表示法+hash)
1282 时钟 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有N个时钟,每个时钟有M个指针,P个刻度.时钟是圆形的,P个刻度均分整 ...
- JFrame上添加、删除Jpanel后动态显示界面问题
JFrame中动态添加或者删除JPanel后总是不正确显示需要的界面问题: 1.删除panel后还是显示之前的界面,新删除的panel在界面上并没有被删除: 2.删除panel1后添加新的panel2 ...
- bash常见命令
pwd (Print Working Directory) 查看当前目录 cd (Change Directory) 切换目录,如 cd /etc ls (List) 查看当前目录下内容,如 ls - ...
- Python3.6全栈开发实例[005]
5.接收两个数字参数,返回比较大的那个数字. def compare(a,b): return a if a > b else b # 三元表达式 print(compare(20,100))
- 我的Android进阶之旅------>Android 众多的布局属性详解
Android功能强大,界面华丽,但是众多的布局属性就害苦了开发者,下面这篇文章结合了网上不少资料,希望对读者有用. 第一类:属性值为true或false android:layout_centerH ...