首页 > 其他 > 详细

D. Cut

时间:2021-04-24 00:40:08      阅读:21      评论:0      收藏:0      [点我收藏+]

分解质因数,发现一个子区间内要保持互质关系才能满足 乘积==lcm

贪心思想找到当前点最远能到的点,此处可以用双指针

倍增优化查询时跳的速度。

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const ll mod = 1e9+7;
const ll maxn = 2e5+10;
ll x,y,k,n,a[maxn],st[maxn][50];//记录当前位置实际跳转的+1位 
ll cnt[maxn];//桶记录质数个数 
void q(){
    ll ans=0;
    cin>>x>>y;
    for(int i=30;i>=1;--i){
        if(st[x][i]<=y){//记录的是+1位,所以相等还没有到 
            ans=ans+(1ll<<(i-1));
            x=st[x][i];
        }
    }
    cout<<(ans+1)<<"\n";
}
void pop(int x){
    for(int i=2;i*i<=x;++i){
        while(x%i==0){
            x=x/i;
            cnt[i]--;
        }
    }
    if(x>1)    cnt[x]--;
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>k;
    for(int i=1;i<=n;++i){
        cin>>a[i];
    }
    int p1=1,p2=1;//双指针贪心 
    while(p2<=n){
        int x=a[p2];
        for(int i=2;i*i<=x;++i){
            if(x%i==0){
                while(cnt[i]){//不满足互质关系 
                    st[p1][1]=p2;
                    pop(a[p1]);
                    p1++;
                }
                while(x%i==0){//加上当前质数 
                    x=x/i;
                    cnt[i]++;
                }
            }
        }
        if(x>1){
            while(cnt[x]){//不满足互质关系 
                st[p1][1]=p2;
                pop(a[p1]);
                p1++;
            }
            cnt[x]++;
        }
        p2++;
    }
    while(p1!=p2){//p2==n+1
        st[p1][1]=p2;p1++; 
    }
    for(int i=0;i<=30;++i){//界限位置怎么跳都是这样 
        st[n+1][i]=n+1;
    }
    for(int i=n;i>=1;--i){
        for(int j=2;j<=30;++j){
            ll nxt=min(n+1,st[i][j-1]);
            st[i][j]=st[nxt][j-1];
        }
    }
    for(int i=1;i<=k;++i)q(); 
    return 0;
}

 

D. Cut

原文:https://www.cnblogs.com/PdrEam/p/14695577.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!