2013年 ACMICPC 杭州赛区H题

思路:树状数组统计。待验证,不知道是否对。 

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x&(-x))
#define Maxn 200010
using namespace std;
int C[Maxn],vi[Maxn],pre[Maxn],n,num[Maxn],ans[Maxn],ov[Maxn];
struct Qu{
    int l,r,i;
}q[Maxn];
int cmp(Qu a,Qu b)
{
    return a.r<b.r;
}
void update(int pos,int val)
{
    while(pos){
        C[pos]+=val;
        pos-=lowbit(pos);
    }
}
int sum(int pos)
{
    int s=0;
    while(pos<=n){
        s+=C[pos];
        pos+=lowbit(pos);
    }
    return s;
}
int main()
{
    int m,i,j;
    while(scanf("%d%d",&n,&m),n||m){
        memset(C,0,sizeof(C));
        memset(vi,0,sizeof(vi));
        memset(pre,0,sizeof(pre));
        memset(ov,0,sizeof(ov));
        for(i=1;i<=n;i++)
            scanf("%d",num+i);
        for(i=1;i<=m;i++){
            scanf("%d%d",&q[i].l,&q[i].r);
            q[i].i=i;
        }
        sort(q+1,q+1+m,cmp);
        int r=1,temp,pos;
        for(i=1;i<=n;i++){
            update(i,1);
            pos=0;
            for(j=2;j*j<=num[i];j++){
                if(num[i]%j) continue;
                if(!vi[pre[j]]&&pre[j]) {
                    update(pre[j],-1);
                    if(ov[pre[j]])
                        update(ov[pre[j]],1);
                    vi[pre[j]]=1;
                }
                pos=max(pos,pre[j]);
                pre[j]=i;
                if(j*j==num[i]) continue;
                temp=num[i]/j;
                if(!vi[pre[temp]]&&pre[temp]){
                    update(pre[temp],-1);
                    if(ov[pre[temp]])
                        update(ov[pre[temp]],1);
                    vi[pre[temp]]=1;
                }
                pos=max(pos,pre[temp]);
                pre[temp]=i;
            }
            if(!vi[pre[num[i]]]&&pre[num[i]]){
                update(pre[num[i]],-1);
                if(ov[pre[num[i]]])
                        update(ov[pre[num[i]]],1);
                vi[pre[num[i]]]=1;
            }
            pos=max(pos,pre[num[i]]);
            pre[num[i]]=i;
            if(pos){
                update(pos,-1);
                ov[i]=pos;
            }
            while(r<=m&&q[r].r==i){
                ans[q[r].i]=sum(q[r].l);
                r++;
            }
        }
        for(i=1;i<=m;i++)
            printf("%d\n",ans[i]);
    }
    return 0;
}

 

posted @ 2013-10-28 19:24  fangguo  阅读(204)  评论(0编辑  收藏  举报