您的位置:首页 > 大数据 > 人工智能

HDU 4630 No Pain No Game(树状数组)

2013-08-01 09:33 351 查看
题目链接

看的别人的题解,离线之后,按r排序,枚举1-n,利用pre[j],存上次j的倍数出现的位置,树状数组里统计的当前位置到最后的最大值,树状数组是求区间最值其实应该很麻烦的,但是此题用法只是求到最后的最大值,插入的时候,往前更新就好了,类似求和。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int num[50100];
int p[50100];
int n;
struct node
{
int l,r,id;
} que[50001];
bool cmp(node a,node b)
{
return a.r < b.r;
}
bool cmp1(node a,node b)
{
return a.id < b.id;
}
int pre[50101];
int ans[50101];
int lowbit(int t)
{
return t&(-t);
}
void insert(int t,int d)
{
while(t)
{
p[t] = max(p[t],d);
t -= lowbit(t);
}
}
int getmax(int t)
{
int maxz = 0;
while(t <= n)
{
maxz = max(maxz,p[t]);
t += lowbit(t);
}
return maxz;
}
int main()
{
int i,j,t,m,tnum;
scanf("%d",&t);
while(t--)
{
memset(p,0,sizeof(p));
memset(pre,0,sizeof(pre));
scanf("%d",&n);
for(i = 1; i <= n; i ++)
scanf("%d",&num[i]);
scanf("%d",&m);
for(i = 0; i < m; i ++)
{
scanf("%d%d",&que[i].l,&que[i].r);
que[i].id = i;
}
sort(que,que+m,cmp);
tnum = 0;
for(i = 1; i <= n; i ++)
{
if(tnum == m) break;
for(j = 1; j*j <= num[i]; j ++)
{
if(num[i]%j == 0)
{
if(pre[j] != 0)
insert(pre[j],j);
pre[j] = i;
if (j * j== num[i]) continue ;
if(pre[num[i]/j] != 0)
insert(pre[num[i]/j],num[i]/j);
pre[num[i]/j] = i;
}
}
while(tnum < m&&que[tnum].r == i)
{
ans[que[tnum].id] = getmax(que[tnum].l);
tnum ++;
}
}
sort(que,que+m,cmp1);
for(i = 0;i < m;i ++)
{
if(que[i].l == que[i].r)
printf("0\n");
else
printf("%d\n",ans[i]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: