zoukankan      html  css  js  c++  java
  • [清华集训2014]奇数国

    OJ题号:
    UOJ38、BZOJ3813

    题目大意:
    一个长度为$1000000$的数列,提供以下两种操作:
    1.修改某一点的数;
    2.求某一区间乘积的欧拉函数。
    保证每个元素的最大质因数不超过$281$,答案对$19961933$取模。

    思路:
    $varphi(n)=n(1-frac{1}{p_1})(1-frac{1}{p_2})...(1-frac{1}{p_l})$,其中$p$为$n$的不同的质因数。
    可以发现欧拉函数值只与$n$和$p$有关。
    所以可以用线段树维护每个区间的乘积,因为$281$是第$60$个质数,因此可以再用一个unsigned long long压位存储每个质数是否出现。
    最后套用欧拉函数公式,除法运算相当于乘以逆元。

    实现细节:
    注意位运算中的1<<i默认是int类型,要转为1ull<<i,否则会WA5个点。

     1 #include<map>
     2 #include<cmath>
     3 #include<cstdio>
     4 #include<cctype>
     5 #include<vector>
     6 inline int getint() {
     7     char ch;
     8     while(!isdigit(ch=getchar()));
     9     int x=ch^'0';
    10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    11     return x;
    12 }
    13 const int N=1000001,n=1000000,mod=19961993;
    14 std::map<int,int> id;
    15 inline bool isPrime(const int x) {
    16     for(int i=2;i<=floor(sqrt(x));i++) if(!(x%i)) return false;
    17     return true;
    18 }
    19 std::vector<int> v;
    20 int inv[282];
    21 class SegmentTree {
    22     #define mid ((b+e)>>1)
    23     #define _left <<1
    24     #define _right <<1|1
    25     private:
    26         int val[N<<2];
    27         unsigned long long prime[N<<2];
    28         void push_up(const int p) {
    29             val[p]=(long long)val[p _left]*val[p _right]%mod;
    30             prime[p]=prime[p _left]|prime[p _right];
    31         }
    32         std::pair<int,unsigned long long> query(const int p,const int b,const int e,const int l,const int r) {
    33             if((b==l)&&(e==r)) return std::make_pair(val[p],prime[p]);
    34             std::pair<int,unsigned long long> q1=std::make_pair(1,0),q2=std::make_pair(1,0),ret;
    35             if(l<=mid) q1=query(p _left,b,mid,l,std::min(mid,r));
    36             if(r>mid) q2=query(p _right,mid+1,e,std::max(mid+1,l),r);
    37             ret.first=(long long)q1.first*q2.first%mod;
    38             ret.second=q1.second|q2.second;
    39             return ret;
    40         }
    41     public:
    42         void build(const int p,const int b,const int e) {
    43             if(b==e) {
    44                 val[p]=3;
    45                 prime[p]=2;
    46                 return;
    47             }
    48             build(p _left,b,mid);
    49             build(p _right,mid+1,e);
    50             push_up(p);
    51         }
    52         void modify(const int p,const int b,const int e,const int x,const int y) {
    53             if(b==e) {
    54                 val[p]=y;
    55                 prime[p]=0;
    56                 for(unsigned i=0;i<v.size();i++) {
    57                     if(!(y%v[i])) prime[p]|=1ull<<i;
    58                 }
    59                 return;
    60             }
    61             if(x<=mid) modify(p _left,b,mid,x,y);
    62             if(x>mid) modify(p _right,mid+1,e,x,y);
    63             push_up(p);
    64         }
    65         int phi(const int p,const int b,const int e,const int l,const int r) {
    66             std::pair<int,unsigned long long> tmp=query(1,1,n,l,r);
    67             int ans=tmp.first;
    68             for(unsigned i=0;i<60;i++) {
    69                 if(tmp.second&(1ull<<i)) {
    70                     ans=(long long)ans*(v[i]-1)%mod*inv[v[i]]%mod;
    71                 }
    72             }
    73             return ans;
    74         }
    75 };
    76 SegmentTree t;
    77 int main() {
    78     inv[1]=1;
    79     for(int i=2,cnt=0;i<=281;i++) {
    80         if(isPrime(i)) {
    81             id[i]=cnt++;
    82             v.push_back(i);
    83         }
    84         inv[i]=(long long)(mod-mod/i)*inv[mod%i]%mod;
    85     }
    86     int x=getint();
    87     t.build(1,1,n);
    88     for(int i=1;i<=x;i++) {
    89         int a=getint(),b=getint(),c=getint();
    90         if(a) {
    91             t.modify(1,1,n,b,c);
    92         }
    93         else {
    94             printf("%d
    ",t.phi(1,1,n,b,c));
    95         }
    96     }
    97     return 0;
    98 }

     事实上质数只有60个,所以可以直接打表。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<algorithm>
     4 inline int getint() {
     5     char ch;
     6     while(!isdigit(ch=getchar()));
     7     int x=ch^'0';
     8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     9     return x;
    10 }
    11 const int N=1000001,n=1000000,mod=19961993;
    12 const int v[60]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281};
    13 const int inv[60]={9980997,6653998,11977196,8555140,5444180,1535538,10568114,14708837,3471651,11701858,17386252,1618540,16066970,2321162,18263100,16948862,12518538,15380552,10725847,1686929,13399146,17182475,12025297,15924736,13582387,395287,6395590,15857658,16299242,6359573,3300802,18742940,6702567,10914471,16210746,11765678,5340151,18247466,7769638,8077107,11932588,6506948,1985748,6619521,5877135,4413707,9744480,10115270,14597757,16475182,18334191,5011379,18885205,7555336,621385,11309266,12170137,12006660,18304499,11153142};
    14 class SegmentTree {
    15     #define mid ((b+e)>>1)
    16     #define _left <<1
    17     #define _right <<1|1
    18     private:
    19         int val[N<<2];
    20         unsigned long long prime[N<<2];
    21         void push_up(const int p) {
    22             val[p]=(long long)val[p _left]*val[p _right]%mod;
    23             prime[p]=prime[p _left]|prime[p _right];
    24         }
    25         std::pair<int,unsigned long long> query(const int p,const int b,const int e,const int l,const int r) {
    26             if((b==l)&&(e==r)) return std::make_pair(val[p],prime[p]);
    27             std::pair<int,unsigned long long> q1=std::make_pair(1,0),q2=std::make_pair(1,0),ret;
    28             if(l<=mid) q1=query(p _left,b,mid,l,std::min(mid,r));
    29             if(r>mid) q2=query(p _right,mid+1,e,std::max(mid+1,l),r);
    30             ret.first=(long long)q1.first*q2.first%mod;
    31             ret.second=q1.second|q2.second;
    32             return ret;
    33         }
    34     public:
    35         void build(const int p,const int b,const int e) {
    36             if(b==e) {
    37                 val[p]=3;
    38                 prime[p]=2;
    39                 return;
    40             }
    41             build(p _left,b,mid);
    42             build(p _right,mid+1,e);
    43             push_up(p);
    44         }
    45         void modify(const int p,const int b,const int e,const int x,const int y) {
    46             if(b==e) {
    47                 val[p]=y;
    48                 prime[p]=0;
    49                 for(unsigned i=0;i<60;i++) {
    50                     if(!(y%v[i])) prime[p]|=1ull<<i;
    51                 }
    52                 return;
    53             }
    54             if(x<=mid) modify(p _left,b,mid,x,y);
    55             if(x>mid) modify(p _right,mid+1,e,x,y);
    56             push_up(p);
    57         }
    58         int phi(const int p,const int b,const int e,const int l,const int r) {
    59             std::pair<int,unsigned long long> tmp=query(1,1,n,l,r);
    60             int ans=tmp.first;
    61             for(unsigned i=0;i<60;i++) {
    62                 if(tmp.second&(1ull<<i)) {
    63                     ans=(long long)ans*(v[i]-1)%mod*inv[i]%mod;
    64                 }
    65             }
    66             return ans;
    67         }
    68 };
    69 SegmentTree t;
    70 int main() {
    71     t.build(1,1,n);
    72     for(int x=getint();x;x--) {
    73         int a=getint(),b=getint(),c=getint();
    74         if(a) {
    75             t.modify(1,1,n,b,c);
    76         }
    77         else {
    78             printf("%d
    ",t.phi(1,1,n,b,c));
    79         }
    80     }
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    隔离级别
    cookie
    session
    正则表达式
    hello2源代码解析
    servlet_filter简介
    web.xml
    Annotations
    Java design patterna
    CDI Features
  • 原文地址:https://www.cnblogs.com/skylee03/p/7388065.html
Copyright © 2011-2022 走看看