两道离线线段树。

比赛时候没想到。。。。

扫描数组,i从1到n,线段树维护从1到i每一个约数(1~50000)的出现的最近位置,线段树存储的是约数的最大值

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm> using namespace std; const int N=50050; struct Interval{
int l,r,id;
}in[N]; struct Tree{
int l,r,Max;
}tree[N<<2]; int n,m;
int a[N];
int pre[N];
int ans[N];
vector<int> factor[N]; void init(){
for(int i=1;i<N;i++)
for(int j=i;j<N;j+=i)
factor[j].push_back(i);
} bool cmp(struct Interval a,struct Interval b){
return a.r<b.r;
} void build(int l,int r,int id){
tree[id].l=l;
tree[id].r=r;
tree[id].Max=0;
if(l!=r){
int mid=(l+r)>>1;
build(l,mid,id<<1);
build(mid+1,r,id<<1|1);
}
} void update(int pos,int val,int id){
tree[id].Max=max(tree[id].Max,val);
if(tree[id].l==tree[id].r) return ;
int mid=(tree[id].l+tree[id].r)>>1;
if(mid>=pos) update(pos,val,id<<1);
else update(pos,val,id<<1|1);
} int query(int l,int r,int id){
if(tree[id].l==l && tree[id].r==r) return tree[id].Max;
int mid=(tree[id].l+tree[id].r)>>1;
if(mid>=r) return query(l,r,id<<1);
else if(mid<l) return query(l,r,id<<1|1);
else return max(query(l,mid,id<<1),query(mid+1,r,id<<1|1));
} int main(){
init();
int t,T;
int i,j,k;
scanf("%d",&T);
for(t=1;t<=T;t++){
scanf("%d",&n);
build(1,n,1);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
}
scanf("%d",&m);
for(i=0;i<m;i++){
scanf("%d %d",&in[i].l,&in[i].r);
in[i].id=i;
}
sort(in,in+m,cmp);
memset(pre,0,sizeof(pre));
for(i=1,j=0;i<=n && j<m;i++){
for(k=0;k<factor[a[i]].size();k++){
int tem=factor[a[i]][k];
if(pre[tem]!=0){
update(pre[tem],tem,1);
}
pre[tem]=i;
}
while(j<m && in[j].r==i){
ans[in[j].id]=query(in[j].l,in[j].r,1);
j++;
}
}
for(i=0;i<m;i++) printf("%d\n",ans[i]);
}
return 0;
}

BOJ的那题找不到了,做完这道题之后,发现这两题很像,都是离线线段树做法。(这道题还是队友出的,膜拜)

先为数组中每个点i一个最小区间l,r满足a[i]>a[l] && a[i]<a[r],l<i<r

然后i从1开始扫描,每次把能加入的点加入,然后处理右端点为i的查询

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
const int MAXN = 100000+5;
const int INF = 0x3f3f3f3f;
int T, N, Q, a[MAXN], s[MAXN], t[MAXN];
int idq[MAXN], q[MAXN], cnt[MAXN], p[MAXN];
int x[MAXN], y[MAXN], ida[MAXN];
int Tr[MAXN<<2], mark[MAXN<<2];
void Build(int idx, int L, int R)
{
Tr[idx] = mark[idx] = 0;
if (L == R)
return;
int left = idx<<1, right = idx<<1|1, mid = (L+R)>>1;
Build(left, L, mid);
Build(right, mid+1, R);
}
void PushDown(int idx)
{
int left = idx<<1, right = idx<<1|1, &mk = mark[idx];
Tr[left] += mk;
mark[left] += mk;
Tr[right] += mk;
mark[right] += mk;
mk = 0;
}
void Update(int idx, int L, int R, int l, int r, int c)
{
if (l <= L && R <= r)
{
Tr[idx] += c;
mark[idx] += c;
return;
}
if (mark[idx])
PushDown(idx);
int left = idx<<1, right = idx<<1|1, mid = (L+R)>>1;
if (l <= mid)
Update(left, L, mid, l, r, c);
if (mid < r)
Update(right, mid+1, R, l, r, c);
}
int Query(int idx, int L, int R, int x)
{
if (x == L && R == x)
return Tr[idx];
if (mark[idx])
PushDown(idx);
int left = idx<<1, right = idx<<1|1, mid = (L+R)>>1;
if (x <= mid)
return Query(left, L, mid, x);
else
return Query(right, mid+1, R, x);
}
bool cmpq(const int &a, const int &b)
{
return t[a] < t[b];
}
bool cmpa(const int &a, const int &b)
{
return y[a] < y[b];
}
int main()
{
//freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
scanf("%d", &T);
for (int cas = 1; cas <= T; cas++)
{
printf("Case %d:\n", cas);
scanf("%d", &N);
stack<int> stal, star;
a[0] = 0;
stal.push(0);
for (int i = 1; i <= N; i++)
{
scanf("%d", &a[i]);
while (a[i] <= a[stal.top()])
stal.pop();
x[i] = stal.top();
stal.push(i);
}
a[N+1] = INF;
star.push(N+1);
for (int i = N; i >= 1; i--)
{
while (a[i] >= a[star.top()])
star.pop();
y[i] = star.top();
star.push(i);
ida[i] = i;
}
sort(ida+1, ida+1+N, cmpa);
scanf("%d", &Q);
for (int i = 1; i <= Q; i++)
{
scanf("%d%d", &s[i], &t[i]);
if (s[i] > t[i])
swap(s[i], t[i]);
idq[i] = i;
q[i] = 0;
}
sort(idq+1, idq+1+Q, cmpq);
Build(1, 1, N);
for (int i = 1, j = 1, k = 1; i <= N; i++)
{
for (; y[ida[k]] == i && k <= N; k++) if (x[ida[k]])
Update(1, 1, N, 1, x[ida[k]], 1);
for (; t[idq[j]] == i && j <= Q; j++)
q[idq[j]] = Query(1, 1, N, s[idq[j]]);
}
for (int i = 1; i <= Q; i++)
printf("%d\n", q[i]);
}
return 0;
}

HDU 4630、BOJ 某题的更多相关文章

  1. hdu 4630 查询[L,R]区间内任意两个数的最大公约数

    No Pain No Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  2. HDU - 4630 No Pain No Game (线段树 + 离线处理)

    id=45786" style="color:blue; text-decoration:none">HDU - 4630 id=45786" style ...

  3. HDU 4630 No Pain No Game(2013多校3 1010题 离线处理+树状数组求最值)

    No Pain No Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  4. HDU 1102 最小生成树裸题,kruskal,prim

    1.HDU  1102  Constructing Roads    最小生成树 2.总结: 题意:修路,裸题 (1)kruskal //kruskal #include<iostream> ...

  5. hdu 4630 No Pain No Game

    http://acm.hdu.edu.cn/showproblem.php?pid=4630 离散化+树状数组 将数组 *a  从后向前遍历 遍历到 a[x] 的时候 再枚举a[x]的约数 假如 约数 ...

  6. HDU 4493 Tutor 水题的收获。。

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=4493 题意我都不好意思说,就是求12个数的平均数... 但是之所以发博客,显然有值得发的... 这个题最 ...

  7. hdu 1853 最小费用流好题 环的问题

    Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Tota ...

  8. hdu 4802 GPA 水题

    GPA Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4802 Des ...

  9. hdu 5210 delete 水题

    Delete Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5210 D ...

随机推荐

  1. u_boot启动过程中的具体分析(1)

    闭上眼睛,细致的回顾一下从NAND FLASH 启动的整个流程,首先,当我们打开板子的时候,先执行的就是嵌入在芯片上的iROM,它的作用就是为了把.NAND Flash 中的bootloader的一部 ...

  2. Matlab.NET混合编程技巧之——找出Matlab内置函数

    原文:[原创]Matlab.NET混合编程技巧之--找出Matlab内置函数 Matlab与.NET的混合编程,掌握了基本过程,加上一定的开发经验和算法基础,肯定不难.反之,有时候一个小错误,可能抓破 ...

  3. dp related problems (update continuously)

    Leetcode Maximum Product Subarray 这个问题是说给一个整数数组.求最大连续子阵列产品. 纠结了包括阵列中的很长一段时间0而如何处理负数,关键的事实是,负治疗,所以我们录 ...

  4. Spring + Spring MVC + Hibernate项目开发集成(注解)

    在自己从事的项目中都是使用xml配置的方式来进行的,随着项目的越来越大,会发现配置文件会相当的庞大,这个不利于项目的进行和后期的维护.于是考虑使用注解的方式来进行项目的开发,前些日子就抽空学习了一下. ...

  5. CSharp设计模式读书笔记(13):代理模式(学习难度:★★★☆☆,使用频率:★★★★☆)

    代理模式:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问. 模式角色与结构: 示例代码: using System; using System.Collections.Generi ...

  6. Java数据结构与算法(1) - ch02有序表(OrderedArray)

    有序表需要掌握的插入方法,删除方法和二分法查找方法. 插入方法: 从前往后找到比要插入的值大的数组项,将该数组项及之后的项均后移一位(从最后一项起依次后移),最后将要插入的值插入当前数组项. 删除方法 ...

  7. ORA-00932: inconsistent datatypes: expected - got CLOB

    从最近的数据库10.2.0.3升级到10.2.0.5之后,一些对象可以不被编译.查看这些对象的主列表不严格写入之前现在SQL这些语法结果package无法成功编译,诸如select查询列中不能使用混淆 ...

  8. CSS3+HTML5特效5 - 震动的文字

    先看效果(把鼠标移上去看看) abcd 这个效果很简单,就是移动文字的位置模拟出震动的效果. Css <style> @-webkit-keyframes shake { 0%{ -web ...

  9. 深入理解C指针之六:指针和结构体

    原文:深入理解C指针之六:指针和结构体 C的结构体可以用来表示数据结构的元素,比如链表的节点,指针是把这些元素连接到一起的纽带. 结构体增强了数组等集合的实用性,每个结构体可以包含多个字段.如果不用结 ...

  10. MongoDB学习笔记&lt;两&gt;

    继续有shell学问,他们继续研究的例子,下面的知识: --文档数据插入 --文档数据删除 --文档数据更新 如下面的详细信息: 1.插入文档 db.person.insert({"name ...