zoukankan      html  css  js  c++  java
  • HDU 4777 Rabbit Kingdom

    素因子分解,树状数组。$ACM/ICPC$ $2013$杭州区域赛$H$题。

    首先需要处理出数字$a[i]$左边最远到$L[i]$,右边最远到$R[i]$区间内所有数字都与$a[i]$互质。

    那么对于左端点在$[L[i],i]$并且右端点在$[i,R[i]]$的询问,$a[i]$就可以作出一个贡献。

    接下来的问题就可以转化为二维平面上有很多矩形,每次询问一个点被多少矩形覆盖。可以离线操作,类似于扫描线的思想做就可以了。

    素因子分解需要一开始把$20$万个数字都处理好,避免每组测试数据内重复处理。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    
    #include<queue>
    using namespace std;
    
    const int maxn=2e5+10;
    int w[maxn],n,q;
    struct X
    {
        int x,y,ans,id;
    } s[maxn];
    
    struct OP
    {
        int x,y1,y2;
    } add[maxn],del[maxn];
    
    bool com[maxn];
    int primes, prime[maxn],L[maxn],R[maxn];
    int pre[maxn];
    int c[maxn],hh;
    
    vector<int>Prime[maxn];
    
    int lowbit(int x) { return x&(-x); }
    void ADD(int p, int val) { while (p <= n) c[p] = c[p] + val, p = p + lowbit(p); }
    int sum(int p) { int r = 0; while (p > 0) r = r + c[p], p = p - lowbit(p); return r; }
    void update(int L, int R, int val) { ADD(L, val); ADD(R + 1, -val); }
    
    void solve()
    {
        primes = 0;
        memset(com,false,sizeof(com));
        com[0] = com[1] = true;
        for (int i = 2; i < maxn; ++i)
        {
            if (!com[i])
            {
                prime[++primes] = i;
            }
            for (int j = 1; j <= primes && i*prime[j] < maxn; ++j)
            {
                com[i*prime[j]] = true;
                if (!(i % prime[j]))
                    break;
            }
        }
    
        for(int i=2;i<=200000;i++)
        {
            int tp = i;
            for(int j=1;j<=primes&&tp!=1;j++)
            {
                if(tp%prime[j]) continue;
    
                Prime[i].push_back(prime[j]);
    
                while(!(tp%prime[j])) tp /= prime[j];
    
                if(!com[tp]&&tp>1)
                {
                    Prime[i].push_back(tp);
                    break;
                }
            }
        }
    }
    
    
    bool cmp1(X a,X b) { return a.x<b.x; }
    bool cmp2(OP a,OP b) { return a.x<b.x; }
    bool cmp3(X a,X b) { return a.id<b.id; }
    
    int main()
    {
        solve();
    
        while(~scanf("%d%d",&n,&q))
        {
            if(n==0&&q==0) break;
            for(int i=1; i<=n; i++) scanf("%d",&w[i]);
    
            for(int i=1; i<=q; i++) scanf("%d%d",&s[i].x,&s[i].y), s[i].id=i;
            sort(s+1,s+1+q,cmp1);
    
            for(int i=1;i<=200000;i++) pre[i]=0;
            for(int i=1;i<=n;i++)
            {
                if(w[i]==1) L[i]=1;
                else
                {
                    L[i]=0;
                    for(int j=0;j<Prime[w[i]].size();j++)
                    {
                        L[i]=max(L[i],pre[Prime[w[i]][j]]+1);
                        pre[Prime[w[i]][j]]=i;
                    }
                }
            }
    
            for(int i=1;i<=200000;i++) pre[i]=n+1;
            for(int i=n;i>=1;i--)
            {
                if(w[i]==1) R[i]=n;
                else
                {
                    R[i]=n+1;
                    for(int j=0;j<Prime[w[i]].size();j++)
                    {
                        R[i]=min(R[i],pre[Prime[w[i]][j]]-1);
                        pre[Prime[w[i]][j]]=i;
                    }
                }
            }
    
           int sz1=0,sz2=0;
           for(int i=1;i<=n;i++)
           {
                add[sz1].x=L[i]; add[sz1].y1=i; add[sz1].y2=R[i]; sz1++;
                del[sz2].x=i; del[sz2].y1=i;  del[sz2].y2=R[i];  sz2++;
           }
    
           sort(add,add+sz1,cmp2);
           sort(del,del+sz2,cmp2);
    
           int idq=1,idadd=0,iddel=0;
    
           memset(c,0,sizeof c);
    
           for(int i=1;i<=n;i++)
           {
                while(idadd<sz1&&add[idadd].x==i)
                {
                    update(add[idadd].y1,add[idadd].y2,1);
                    idadd++;
                }
                while(idq<=q&&s[idq].x==i)
                {
                    s[idq].ans=sum(s[idq].y);
                    idq++;
                }
                while(iddel<sz2&&del[iddel].x==i)
                {
                    update(del[iddel].y1,del[iddel].y2,-1);
                    iddel++;
                }
           }
    
           sort(s+1,s+1+q,cmp3);
    
           for(int i=1;i<=q;i++) printf("%d
    ",s[i].ans);
    
        }
        return 0;
    }
  • 相关阅读:
    画图(三,进阶之绘制表盘)
    浅谈 Fork/Join
    VS中卸载Visual Assist X
    VS中显示行号
    zabbix server安装(二)
    zabbix监控的基础概念、工作原理及架构(一)
    k8s role
    如何构建 Redis 高可用架构?
    Mysqldump参数大全
    kubespray 一键安装k8s集群
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6012086.html
Copyright © 2011-2022 走看看