zoukankan      html  css  js  c++  java
  • hdu5634 BestCoder Round #73 (div.1)

    Rikka with Phi

     
     Accepts: 5
     
     Submissions: 66
     Time Limit: 16000/8000 MS (Java/Others)
     
     Memory Limit: 131072/131072 K (Java/Others)
    Problem Description

    Rikka and Yuta are interested in Phi function (which is known as Euler's totient function).

    Yuta gives Rikka an array A[1..n]A[1..n] of positive integers, then Yuta makes mm queries.

    There are three types of queries:

    1 ; l ; r1lr

    Change A[i]A[i] into varphi(A[i])φ(A[i]), for all i in [l, r]i[l,r].

    2 ; l ; r ; x2lrx

    Change A[i]A[i] into xx, for all i in [l, r]i[l,r].

    3 ; l ; r3lr

    Sum up A[i]A[i], for all i in [l, r]i[l,r].

    Help Rikka by computing the results of queries of type 3.

    Input

    The first line contains a number T(T leq 100)T(T100) ——The number of the testcases. And there are no more than 2 testcases with n > 10 ^ 5n>105

    For each testcase, the first line contains two numbers n,m(n leq 3 imes 10^5, m leq 3 imes 10^5)n,m(n3×105,m3×105)

    The second line contains nn numbers A[i]A[i]

    Each of the next mm lines contains the description of the query.

    It is guaranteed that 1 leq A[i] leq 10^71A[i]107 At any moment.

    Output

    For each query of type 3, print one number which represents the answer.

    Sample Input
    1
    10 10
    56 90 33 70 91 69 41 22 77 45
    1 3 9
    1 1 10
    3 3 8
    2 5 6 74
    1 1 8
    3 1 9
    1 2 10
    1 4 9
    2 8 8 69
    3 3 9
    Sample Output
    80
    122
    86
    /*
    BestCoder Round #73 (div.1)
    hdu5634	Rikka with Phi
    本来最开始用伸展树(主要是线段树不是很熟)的,但是中间有点问题,导致一直是TLE,于是乎
    就去写线段树了
    感觉对线段树的理解上有很多问题TAT
    思路:先打个表然后用线段树(平衡树)去解决
    主要是有same标记,sum和,欧拉
    中间在将一个区间改变成欧拉时,如果中间遇到了区间的same,直接
    修改这个标记就好的
    hhh-2016-02-25 17:54:59
    */
    
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    
    const int maxn = 300010;
    ll euler[10000010] = {0};
    void getEuler()
    {
        euler[1] = 1;
        for(ll i =2 ; i <= 10000000; i++)
        {
            if(!euler[i])
            {
                for(ll j = i; j <= 10000000; j += i)
                {
                    if(!euler[j])
                        euler[j] = j;
                    euler[j] = euler[j]/i*(i-1);
                }
            }
        }
    }
    
    struct node
    {
        int l,r;
        ll sum,same;
    } segtree[maxn<<2];
    
    void push_up(int r)
    {
        int lson = r<<1,rson = (r<<1)|1;
        segtree[r].sum = segtree[lson].sum + segtree[rson].sum;
        if(segtree[lson].same == segtree[rson].same)
            segtree[r].same = segtree[lson].same;
        else
            segtree[r].same = 0;
    }
    
    void build(int i ,int l,int r)
    {
        segtree[i].l = l,segtree[i].r = r;
        segtree[i].sum = segtree[i].same = 0;
        if(l == r)
        {
            scanf("%I64d",&segtree[i].same);
            segtree[i].sum = segtree[i].same;
            return ;
        }
        int mid = (l+r)>>1;
        build(i<<1,l,mid);
        build((i<<1)|1,mid+1,r);
        push_up(i);
    }
    
    
    void push_down(int r)
    {
        int lson = r<<1,rson = (r<<1)|1;
        if(segtree[r].same)
        {
            segtree[lson].same = segtree[r].same;
            segtree[rson].same = segtree[r].same;
            segtree[lson].sum = (ll)(segtree[lson].r - segtree[lson].l+1)*segtree[r].same;
            segtree[rson].sum = (ll)(segtree[rson].r - segtree[rson].l+1)*segtree[r].same;
            segtree[r].same = 0;
        }
    }
    
    void make_euler(int i,int l,int r)
    {
        //区间修改
        if(segtree[i].r <= r && segtree[i].l >= l && segtree[i].same)
        {
            segtree[i].same  = (ll)euler[segtree[i].same];
            segtree[i].sum = segtree[i].same*(ll)(segtree[i].r-segtree[i].l+1);
            return;
        }
        if(l == r) return ;
        int mid = (segtree[i].r +segtree[i].l) >>1;
        push_down(i);
        if(l <= mid)
            make_euler(i<<1,l,r);
        if(r > mid)
            make_euler((i<<1)|1,l,r);
        push_up(i);
    }
    void make_same(int i,int l,int r,ll c)
    {
        if(segtree[i].r <= r && segtree[i].l >= l)
        {
            segtree[i].same = c;
            segtree[i].sum = segtree[i].same*(ll)(segtree[i].r-segtree[i].l+1);
            return;
        }
        int mid = (segtree[i].r +segtree[i].l) >>1;
        push_down(i);
        if(l <= mid)
            make_same(i<<1,l,r,c);
        if(r > mid)
            make_same((i<<1)|1,l,r,c);
        push_up(i);
    }
    
    ll get_sum(int i,int l,int r)
    {
        int mid = (segtree[i].l + segtree[i].r) >> 1;
        if(segtree[i].l >= l && segtree[i].r <= r)
        {
            return segtree[i].sum;
        }
        push_down(i);
        ll ans = 0;
        if(l <= mid) ans += get_sum(i<<1,l,r);
        if(r > mid) ans += get_sum(i<<1|1,l,r);
        push_up(i);
        return ans;
    }
    
    int main()
    {
        int T,n,m;
        getEuler();
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            build(1,1,n);
            for(int i =1; i <= m; i++)
            {
                int op,l,r;
                ll c;
                scanf("%d",&op);
                if(op == 1)
                {
                    scanf("%d%d",&l,&r);
                    make_euler(1,l,r);
                    //debug();
                }
                else if(op == 2)
                {
                    scanf("%d%d%I64d",&l,&r,&c);
                    make_same(1,l,r,c);
                    // debug();
                }
                else if(op == 3)
                {
                    scanf("%d%d",&l,&r);
                    printf("%I64d
    ",get_sum(1,l,r));
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    [转载]linux下svn命令使用大全
    【转载】Js获取当前日期时间及其它操作
    【转载】checkbox复选框的一些深入研究与理解
    IDEA13中配置struts错误:ClassNotFoundException: org...dispatcher.ng.filter.StrutsPrepareAndExecuteFilter +找不到java程序包 解决办法
    【转】jQuery.extend 函数详解
    【转载】Highcharts使用指南
    [转载]几个开源Javascript图形库
    sqlserver数据库创建快照发布遇到的错误:对路径“XXXX”访问被拒绝
    服务器安装ubuntu 14.04 server,开机启动屏幕不停滚动错误WRITE SAME failed. Manually zeroing
    NAT 模式下虚拟机安装的centos7 ping主机显示connect: Network is unreachable
  • 原文地址:https://www.cnblogs.com/Przz/p/5409617.html
Copyright © 2011-2022 走看看