Codeforces round #717 D.Cut(m询问求区间[L,R]能被至少分成多少个区间让每个小区间各数的乘积==各数的LCM)

题:https://codeforces.com/contest/1516/problem/D

题意:给定n(n<=1e5)个数,q(n<=1e5)个询问,[L,R],问:[L,R]能被至少分成多少个区间让每个小区间各数的乘积==各数的LCM

分析:

  • 考虑最简单的求法,对于每个 l ,求出b[l],使得[ l, b[l] ]满足题意,然后迭代l = b[l] 直到 l 超过 r,计数结束;
  • 简化这个迭代的过程,考虑dp[ i ][ j ]表示进行了 j = b[ j ] 这个操作 2 ^ i 次到达的位置;
  • 而只要算出每个位置迭代1次(即迭代2^0次)就能递推出所有dp[ i ][ j ]( 因为可以满足dp[ i ][ j ] = dp[i - 1][ dp[i - 1][ j ] ] );
  • 对于迭代一次的可以预处理每个数的质数,然后从后往前枚举离当前位置pos最近又含与a[pos]不互质的位置 j ,这个位置 j 就是pos迭代一次要跳的位置;
  • 因为询问的[L, R]之间的距离肯定可以由一个二进制数来定,所以可以用这个方法。
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define MP make_pair
#define UM unordered_map
#define pii pair<int,int>
#define lson root<<1,l,midd
#define rson root<<1|1,midd+1,r
#define lc root<<1
#define rc root<<1|1
typedef long long ll;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const ll INF=1e18;
#define pi 3.1415926535898
#define DEC (pi/180)
const int M=1e5+5;
vector<int>vec[M];
int dp[20][M*10],nextt[M],a[M];
int n,q;
void init(){
    for(int i=2;i<M;i++){
        if(vec[i].size()==0){
            nextt[i]=n+1;
            for(int j=i;j<M;j+=i){
                vec[j].pb(i);
            }
        }
    }
}
int main(){

    int T;
    ///scanf("%d",&T);
    T=1;
    while(T--){
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++){
            nextt[i]=n+1;
            scanf("%d",&a[i]);
        }
        init();
        dp[0][n+1]=n+1;
        for(int j=n;j>=1;j--){
            dp[0][j]=dp[0][j+1];
            for(auto v:vec[a[j]]){
                dp[0][j]=min(dp[0][j],nextt[v]);
                nextt[v]=j;
            }
        }
        for(int i=1;i<20;i++)
            for(int j=1;j<=n+1;j++)
                dp[i][j]=dp[i-1][dp[i-1][j]];
        while(q--){
            int L,R;
            scanf("%d%d",&L,&R);
            int ans=1;
            for(int i=19;i>=0;i--){
                if(dp[i][L]<=R){
                    ans+=(1<<i);
                    L=dp[i][L];
                }
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}
View Code

 

posted @ 2021-04-22 14:22  starve_to_death  阅读(88)  评论(0编辑  收藏  举报