BZOJ:4869: [Shoi2017]相逢是問候


4869: [Shoi2017]相逢是問候

  先說點正經的……

  顯然做了有限次(我只知道是有限次,而且不會大,別人說是log次?)修改以后會達到不動點,即以后怎么修改都不變了。

  然后就隨便做了。(3個log不知道是不是暴力啊)

  但是需要拓展歐拉定理:

  p與a不互質時,設c=b mod φ(p)(專門設出來是因為公式不能正常顯示),如果b>=φ(p):$a^b ≡ a^{c+φ(p)}$(注意b<φ(p)的時候不能用)

  要證明的話可以用數學歸納法證。

 

 

可是題目翻車了……

大家都質疑題目數據有問題

 

得知這一點,窩的瓜心是崩潰的。

這可是省選題,關系到六個省的oier的命運。

我認識的幾位dalao就參加了這場省選,有的進隊,有的從此AFO。

過幾天我也要省選了,要是出了類似的差錯被卡退役,西瓜可是不會同意的。

為退役的選手們惋惜,也只能祝他們高考加油了。

(也許過幾天就輪到我了呢?

瓜之將死,其言也善

 

upd:后來bzoj上數據更正了呢

 

#include<cstdio>
#include<algorithm>
#define MN 100001
#define lp p<<1
#define rp (p<<1)|1
using namespace std;

int read_p,read_ca;
inline int read(){
    read_p=0;read_ca=getchar();
    while(read_ca<'0'||read_ca>'9') read_ca=getchar();
    while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar();
    return read_p;
}
int n,m,MOD,c,w=0,S[MN],W[MN],a[MN],P[MN],num=0,t,l,r,sum[MN<<2];
bool bo[MN<<2],bi[MN];
inline void M(int &x){while(x>=MOD)x-=MOD;}
inline int mi(int x,int y,int MOD,bool &bi){
    int mmh=1;
    bool fx=0;
    while (y){
        if (y&1) bi|=fx|(1LL*x*mmh>=MOD),mmh=1LL*mmh*x%MOD;
        fx|=1LL*x*x>=MOD;x=1LL*x*x%MOD;y>>=1;
    }
    return mmh;
}
inline int phi(int p){
    int o=1;
    for (int i=1;P[i]*P[i]<=p&&i<=num;i++)
    if (p%P[i]==0){
        p/=P[i];o*=P[i]-1;
        while (p%P[i]==0) p/=P[i],o*=P[i];
    }
    if (p-1) o*=p-1;
    return o;
}
void work(int p){
    S[w++]=p;
    if (p==1) return;
    work(phi(p));
}
int Mavis(int a,int L){
    int mmh=a%S[L];
    bool bi=a>=S[L];
    for (int k=L;k;k--) mmh=mi(c,mmh+(bi?S[k]:0),S[k-1],bi);
    return mmh;
}
void cg(int p,int l,int r,int L,int R){
    if (bo[p]) return;
    if (l==r) {W[l]++;bo[p]=(W[l]==w-1);sum[p]=Mavis(a[l],W[l]);return;}
    int mid=l+r>>1;
    if (R<=mid) cg(lp,l,mid,L,R);else
    if (L>mid) cg(rp,mid+1,r,L,R);else
    cg(lp,l,mid,L,mid),cg(rp,mid+1,r,mid+1,R);
    bo[p]=bo[lp]&bo[rp];
    M(sum[p]=sum[lp]+sum[rp]);
}
void build(int p,int l,int r){
    bo[p]=0;
    if (l==r) sum[p]=a[l];else{
        int mid=l+r>>1;
        build(lp,l,mid);build(rp,mid+1,r);
        M(sum[p]=sum[lp]+sum[rp]);
    }
}
int ask(int p,int l,int r,int L,int R){
    if (l>=L&&r<=R) return sum[p];
    if (l>R||r<L) return 0;
    int mid=l+r>>1;
    return (ask(lp,l,mid,L,R)+ask(rp,mid+1,r,L,R))%MOD;
}
int main(){
    register int i,j,k;
    n=read();m=read();MOD=read();c=read();
    for (i=2;i*i<=MOD;i++){
        if (!bo[i]) P[++num]=i;
        for (j=1;j<=num&&i*P[j]*i*P[j]<=MOD;j++) if (bo[i*P[j]]=1,i%P[j]==0) break;
    }
    work(MOD);S[w++]=1;
    for (i=1;i<=n;i++) a[i]=read(),W[i]=0;
    build(1,1,n);
    while (m--) if (t=read(),l=read(),r=read(),t==0) cg(1,1,n,l,r);else printf("%d\n",ask(1,1,n,l,r));
}
View Code

 

upd:后來我退役了呢


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM