• “美登杯”上海市高校大学生程序设计 E. 小花梨的数组 (线段树)


    https://acm.ecnu.edu.cn/contest/173/problem/E/

    分析:

    考虑这样一种情况,如果对一个点连续地做几次乘操作,那么之后紧跟着的除操作只需要将乘操作的次数减少即可。(因为如果当前是乘于的最小素因子后面肯定也是除上这个)

    那么对这个点的操作将会变成连续的一段乘或者除。如果一段除操作之后出现了乘操作,那只能在一段除之后做一段乘操作了,因为执行了除之后minprime可能会变化。(很显然)

    所以最后对这个点的操作将会变成一段除操作跟着一段乘操作。

    那么就可以利用线段树维护这样一段操作的除乘的个数了。线段树每个节点维护两个信息:除操作个数,乘操作个数

    收获:对线段树的强大操作再一次的认识了!

    #include<bits/stdc++.h>
    using namespace std;
    #define lc ((o) << 1)
    #define rc ((o) << 1 | 1)
    #define ll long long
    const int N = 100010;
    const int MOD = 1e9+7;
    int Mul[N<<2],Div[N<<2],a[N];
    
    void powndown(int o , int l , int r)
    {
        if(Mul[o] || Div[o])
        {
           if(Mul[lc]>=Div[o])
           {
               Mul[lc]-=Div[o];
           }
           else
           {
               Div[lc]+=(Div[o]-Mul[lc]);
               Mul[lc]=0;
           }
    
           if(Mul[rc]>=Div[o])
           {
               Mul[rc]-=Div[o];
           }
           else
           {
               Div[rc]+=(Div[o]-Mul[rc]);
               Mul[rc]=0;
           }
           Mul[lc]+=Mul[o];
           Mul[rc]+=Mul[o];
           Mul[o]=Div[o]=0;
        }
    }
    void update(int o, int l, int r, int L, int R, int tree[], int op)
    {
        if(L <= l && R >= r)
        {
            if(op == 1)tree[o]++;
            else
            {
                if(Mul[o])Mul[o]--;
                else tree[o]++;
            }
            return;
        }
        powndown(o, l, r);
        int m = (l + r) / 2;
        if(L <= m)update(lc, l, m, L, R, tree, op);
        if(R > m)update(rc, m + 1, r, L, R, tree, op);
    }
    
    void query(int o, int l, int r, int x, int& divnum, int& mulnum)
    {
        if(l == r)
        {
            divnum = Div[o];
            mulnum = Mul[o];
            return;
        }
        powndown(o, l, r);
        int m = (l + r) / 2;
        if(x <= m)query(lc, l, m, x, divnum, mulnum);
        else query(rc, m + 1, r, x, divnum, mulnum);
    }
    int tot;
    bool vis[N];
    int pr[N];
    void init()
    {
        tot=0;
        for(int i=2 ; i<=N ; i++)
        {
            if(vis[i]==0)
            {
                pr[++tot]=i;
                //cout<<i<<" "<<pr[10]<<endl;
                for(int j=2*i;j<=N;j+=i)
                vis[j]=1;
            }
        }
    }
    vector<int>FA[N];
    ll POW(ll x , ll y)
    {
        ll ans=1;
        while(y)
        {
            if(y&1) ans=ans*x%MOD;
            y>>=1;
            x=x*x%MOD;
        }
        return ans;
    }
    int main()
    {
    
        int n,m;scanf("%d%d",&n,&m);
        init();
        //cout<<pr[1]<<" "<<pr[2]<<endl;
        for(int i=1 ; i<=n ; i++)
        {
            scanf("%d",&a[i]);
            int x=a[i];
    
            for(int j=1 ; j<=tot&&pr[j]*pr[j]<=x;j++)
            {
                while(x%pr[j]==0)
                {
                    x/=pr[j];
                    FA[i].push_back(pr[j]);
                }
    
            }
            if(x!=1) FA[i].push_back(x);
           // cout<<FA[i].size()<<endl;
        }
    
    
        while(m--)
        {
            int op,l,r;scanf("%d",&op);
            if(op==1)
            {
                scanf("%d%d",&l,&r);
                update(1,1,n,l,r,Mul,1);
            }
            else if(op==2)
            {
                scanf("%d%d",&l,&r);
                update(1,1,n,l,r,Div,2);
            }
            else
            {
                scanf("%d",&l);
                int numMul=0,numDiv=0;
                query(1,1,n,l,numDiv,numMul);
    //            cout<<numDiv<<" "<<numMul<<endl;
    //            cout<<FA[l].size()<<endl;
                if(numDiv>=FA[l].size())
                {
                    puts("1");
                }
                else
                {
                    ll ans=1,tmp=FA[l][numDiv];
    
                    for(int i=numDiv ; i<FA[l].size();i++)
                    ans=(ans*(1ll*FA[l][i]))%MOD;
                    ans=(ans*POW(tmp,numMul))%MOD;
                    printf("%lld
    ",ans);
                }
            }
        }
    }
    View Code
  • 相关阅读:
    菜鸟小试牛刀。。
    RDBMS中部分关于可用性的特性
    ORA01403:no data found exception的解决小道
    oracle的存储结构(一)
    过度使用DBLINK带来的问题
    如何远程指定查询分区表的某个分区
    oracle显式游标不关闭、不关闭就再次打开会不会报错?
    Http方式下载Servlet实现
    Javazip压缩文件乱码问题
    mysql “Access denied for user 'root'@'localhost'
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/10896692.html
Copyright © 2020-2023  润新知