[ZOJ3886]Nico Number(線段樹)__線段樹

來源:互聯網
上載者:User
題目:

我是超連結 題意:

niconico數:所有比x小的數且與x互質的數,從小到大排列是一個等差數列,則x為niconico數。
長度為10^5的數組。三種操作:

第一:詢問區間[l,r] niconico數的個數

第二:將區間 [ l , r ] 的數對v模數

第三:將某一個數更新為x 題解:

首先我們打個表看看這個數,然後我們可以發現,一個數是niconico數有以下3種情況 是質數 是2^x 是6

真是坑人,0&1也屬於niconico。。 代碼:

#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int N=100005;const int C=1e7;bool vis[C+5],ss[C+5];int pri[C+5],sum[N*4],maxx[N*4],tot,a[N];void init(){    for (int i=2;i<=C;i++)    {        if (!ss[i]) vis[i]=true,pri[++tot]=i;        for (int j=1;j<=tot && pri[j]*i<=C;j++)        {            ss[pri[j]*i]=1;            if (i%pri[j]==0) break;        }    }    for (int i=2;i<=C;i*=2) vis[i]=1;    vis[6]=vis[1]=vis[0]=1;}void updata(int now){    sum[now]=sum[now<<1]+sum[now<<1|1];    maxx[now]=max(maxx[now<<1],maxx[now<<1|1]);}void build(int now,int l,int r){    if (l==r)    {        maxx[now]=a[l];        sum[now]=(vis[a[l]]?1:0);        return;    }    int mid=(l+r)>>1;    build(now<<1,l,mid);    build(now<<1|1,mid+1,r);    updata(now);}int qurry(int now,int l,int r,int lrange,int rrange){    if (lrange<=l && rrange>=r) return sum[now];    int mid=(l+r)>>1,ans=0;    if (lrange<=mid) ans+=qurry(now<<1,l,mid,lrange,rrange);    if (rrange>mid) ans+=qurry(now<<1|1,mid+1,r,lrange,rrange);    return ans;}void change(int now,int l,int r,int x,int v){    if (l==r)    {        maxx[now]=v;        sum[now]=(vis[maxx[now]]?1:0);        return;    }    int mid=(l+r)>>1;    if (x<=mid) change(now<<1,l,mid,x,v);    else change(now<<1|1,mid+1,r,x,v);    updata(now);}void qm(int now,int l,int r,int lrange,int rrange,int x){    if (maxx[now]<x) return;        if (l==r)    {        maxx[now]%=x;        sum[now]=(vis[maxx[now]]?1:0);        return;    }    int mid=(l+r)>>1;    if (lrange<=mid) qm(now<<1,l,mid,lrange,rrange,x);    if (rrange>mid) qm(now<<1|1,mid+1,r,lrange,rrange,x);    updata(now);}int main(){    init();int n,m,id;    while (scanf("%d",&n)!=EOF)    {        for (int i=1;i<=n;i++) scanf("%d",&a[i]);        build(1,1,n);        scanf("%d",&m);        for (int i=1;i<=m;i++)        {            int l,r,x;scanf("%d",&id);            if (id==1)            {                scanf("%d%d",&l,&r);printf("%d\n",qurry(1,1,n,l,r));            }else if (id==2)            {                scanf("%d%d%d",&l,&r,&x);                qm(1,1,n,l,r,x);            }else            {                scanf("%d%d",&l,&x);                change(1,1,n,l,x);            }        }    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.