zoukankan      html  css  js  c++  java
  • BZOJ5394: [Ynoi2016]炸脖龙(欧拉广义降幂)

    就是让你求这个:

    传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=5394

    解题思路:

    NOIP2018后第一道题,感觉非常像那个上帝与集合的正确用法。

    具体来说就是使用递归的求解方式,不过这次和上帝与集合的正确用法不同的是:

    1.这次不是无限项,所以可以不在p=0时停止。

    2.因为被取模数有限大,所以要特判小于φ(p)的情况。

    3.询问时要预先处理φ(p)

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lll spc<<1
      5 #define rrr spc<<1|1
      6 #define maxval 20000000
      7 typedef long long lnt;
      8 struct trnt{
      9     lnt val;
     10     lnt lzt;
     11 }tr[2000000];
     12 int prime[20000001];
     13 int eula[20000001];
     14 bool vis[20000001];
     15 int cnt;
     16 int n,m;
     17 lnt a[600000];
     18 lnt read(void)
     19 {
     20     lnt ans=0;
     21     lnt f=1;
     22     char ch=getchar();
     23     while(ch<'0'||ch>'9')
     24     {
     25         if(ch=='-')
     26             f=-f;
     27         ch=getchar();
     28     }
     29     while(ch<='9'&&ch>='0')
     30     {
     31         ans=ans*10ll+(lnt)(ch-'0');
     32         ch=getchar();
     33     }
     34     return ans*f;
     35 }
     36 void Get_prime(void)
     37 {
     38     for(int i=2;i<=maxval;i++)
     39     {
     40         if(!vis[i])
     41         {
     42             prime[++cnt]=i;
     43             eula[i]=i-1;
     44         }
     45         vis[i]=false;
     46         for(int j=1;j<=cnt&&(i*prime[j]<=maxval);j++)
     47         {
     48             vis[i*prime[j]]=true;
     49             if(i%prime[j]==0)
     50             {
     51                 eula[i*prime[j]]=eula[i]*prime[j];
     52                 break;
     53             }
     54             eula[i*prime[j]]=eula[i]*(prime[j]-1);
     55         }
     56     }
     57     return ;
     58 }
     59 void Add(int spc,int l,int r,lnt v)
     60 {
     61     tr[spc].val+=v*(lnt)(r-l+1);
     62     tr[spc].lzt+=v;
     63     return ;
     64 }
     65 void pushup(int spc)
     66 {
     67     tr[spc].val=tr[lll].val+tr[rrr].val;
     68     return ;
     69 }
     70 void pushdown(int spc,int l,int r)
     71 {
     72     if(tr[spc].lzt)
     73     {
     74         int mid=(l+r)>>1;
     75         Add(lll,l,mid,tr[spc].lzt);
     76         Add(rrr,mid+1,r,tr[spc].lzt);
     77         tr[spc].lzt=0;
     78     }
     79     return ;
     80 }
     81 void build(int l,int r,int spc)
     82 {
     83     if(l==r)
     84     {
     85         tr[spc].val=a[l];
     86         return ;
     87     }
     88     int mid=(l+r)>>1;
     89     build(l,mid,lll);
     90     build(mid+1,r,rrr);
     91     pushup(spc);
     92     return ;
     93 }
     94 void update(int l,int r,int ll,int rr,int spc,lnt v)
     95 {
     96     if(ll>r||l>rr)
     97         return ;
     98     if(ll<=l&&r<=rr)
     99     {
    100         Add(spc,l,r,v);
    101         return ;
    102     }
    103     int mid=(l+r)>>1;
    104     pushdown(spc,l,r);
    105     update(l,mid,ll,rr,lll,v);
    106     update(mid+1,r,ll,rr,rrr,v);
    107     pushup(spc);
    108     return ;
    109 }
    110 lnt query(int l,int r,int spc,int pos)
    111 {
    112     if(l==r)
    113         return tr[spc].val;
    114     int mid=(l+r)>>1;
    115     pushdown(spc,l,r);
    116     if(pos<=mid)
    117         return query(l,mid,lll,pos);
    118     return query(mid+1,r,rrr,pos);
    119 }
    120 lnt ksm(lnt a,lnt b,lnt mod,int plc)
    121 {
    122     lnt ans=1;
    123     while(b)
    124     {
    125         if(b&1)
    126         {
    127             ans=ans*a;
    128             if(ans>=mod)
    129             {
    130                 ans%=mod;
    131                 vis[plc]=true;
    132             }
    133         }
    134         a=a*a;
    135         if(a>=mod)
    136         {
    137             a%=mod;
    138             vis[plc]=true;
    139         }
    140         b/=2;
    141     }
    142     return ans;
    143 }
    144 lnt Query(int l,int r,int p)
    145 {
    146     vis[l]=false;   
    147     lnt tmp=query(1,n,1,l);
    148     if(tmp>=p)
    149         vis[l]=true;
    150     tmp%=p;
    151     if(tmp==1)
    152         return 1;
    153     if(p==1)
    154         return 0;
    155     if(l==r)
    156         return tmp%p;
    157     lnt temp=eula[p];
    158     return ksm(tmp,Query(l+1,r,temp)+vis[l+1]*temp,p,l);
    159 }
    160 int main()
    161 {
    162     Get_prime();
    163     n=read();
    164     m=read();
    165     for(int i=1;i<=n;i++)
    166         a[i]=read();
    167     build(1,n,1);
    168     while(m--)
    169     {
    170         lnt cmd=read(),l=read(),r=read(),x=read();
    171         if(cmd==1)
    172             update(1,n,l,r,1,x);
    173         else
    174             printf("%lld
    ",Query(l,r,x));
    175     }
    176     return 0;
    177 }
  • 相关阅读:
    Codeforces 700A As Fast As Possible(二分答案)
    BZOJ 1196 [HNOI2006]公路修建问题(二分答案+并查集)
    Codeforces 701C They Are Everywhere(Two pointers+STL)
    Codeforces 430B Balls Game(Two Pointers)
    CSU 1812 三角形和矩形
    CSU 1804 有向无环图
    CSU 1803 2016
    CSU 1808 地铁
    CodeForces 707B Bakery
    CodeForces 707A Brain's Photos
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9992093.html
Copyright © 2011-2022 走看看