zoukankan      html  css  js  c++  java
  • bzoj:4105: [Thu Summer Camp 2015]平方运算

    Description

     

    Input

    第一行有三个整数N,M,p,分别代表序列的长度、平方操作与询问操作的总次数以及在平方操作中所要模的数。

     
    接下来一行N个数代表一开始的序列{X1,X2,...,XN}。
     
    接下来M行,每行三个整数op,l,r。其中op代表本次操作的类型。若op=0,代表这是一次平方操作,平方的区间为[l,r];如果op=1,代表这是一次询问操作,询问的区间为[l,r]。
     

    Output

    对于每次的询问操作,输出一行代表这段区间内数的总和。注意:答案没有对任何数取模。

     

    Sample Input

    3 3 11
    1 2 3
    1 1 3
    0 1 3
    1 1 3

    Sample Output

    6
    14

    HINT

     对于100%的数据,∀i,Xi∈[0,p),l,r∈[1,n]


    N,M,p的范围如下:

     

    编号  N  M  p

    1  1000  1000  233

    2  1000  1000  2332

    3  100000  100000  5

    4  100000  100000  8192

    5  100000  100000  23

    6  100000  100000  45

    7  100000  100000  37

    8  55000  55000  4185

    9  55000  55000  5850

    10  55000  55000  2975

    11  55000  55000  2542

    12  55000  55000  2015

    13  60000  60000  2003

    14  65000  65000  2010

    15  70000  70000  4593

    16  75000  75000  4562

    17  80000  80000  1034

    18  85000  85000  5831

    19  90000  90000  9905

    20  100000  100000  9977
     
    膜了一大把题解
    线段树是肯定的……
    平方是会出现循环节的(听说会很短
    预处理出所有环,和指向环的链,由于没有其他修改操作,这里面的数字肯定是越修改越往环跑,进了环就处理出跑k次后答案是多少,不在环上就暴力改……
    论权限号的重要性
    /**************************************************************
        Problem: 4105
        User: JSZX11556
        Language: C++
        Result: Accepted
        Time:25216 ms
        Memory:275236 kb
    ****************************************************************/
     
    #include<cstdio>
    #include<algorithm>
    #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,p,a[100001],ne[100001],i;
    bool v[100001],f[100001];
    struct na{
        int l,r,w,le,c,b[63],pos;
        bool v;
    }t[1000000];
    inline int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
    inline int lcm(int x,int y){return x*y/gcd(x,y);}
    inline void updata(int p){
        if (t[p].l==t[p].r) return;
        t[p].w=t[lp].w+t[rp].w;
        t[p].v=t[lp].v&t[rp].v;
        if (t[p].v){
            t[p].pos=0;
            t[p].le=lcm(t[lp].le,t[rp].le);
            for (i=0;i<t[p].le;i++) t[p].b[i]=t[lp].b[(i+t[lp].pos)%t[lp].le]+t[rp].b[(i+t[rp].pos)%t[rp].le];
        }
    }
    inline void build(int p,int l,int r){
        t[p].l=l;t[p].r=r;
        if (l==r){
            t[p].w=a[l];t[p].v=f[t[p].w];
            if (t[p].v) for (t[p].b[0]=t[p].w,t[p].le=1,i=ne[t[p].w];i!=t[p].w;i=ne[i]) t[p].b[t[p].le++]=i;
            return;
        }
        int mid=l+r>>1;
        build(lp,l,mid);build(rp,mid+1,r);
        updata(p);
    }
    inline void hb(int p,int c){
        if (!t[p].v){
            for (i=1;i<=c;i++) t[p].w=ne[t[p].w];t[p].v=f[t[p].w];
            if (t[p].v) for (t[p].b[0]=t[p].w,t[p].le=1,i=ne[t[p].w];i!=t[p].w;i=ne[i]) t[p].b[t[p].le++]=i;
            return;
        }
        c%=t[p].le;
        t[p].c+=c;if (t[p].c>=t[p].le) t[p].c-=t[p].le;
        t[p].pos+=c;if (t[p].pos>=t[p].le) t[p].pos-=t[p].le;
        t[p].w=t[p].b[t[p].pos];
    }
    inline void pd(int p){
        if (t[p].c){
            if (t[p].l!=t[p].r) hb(lp,t[p].c),hb(rp,t[p].c);
            t[p].c=0;
            updata(p);
        }
    }
    inline void ch(int p,int l,int r){
        if (t[p].l==l&&t[p].r==r&&t[p].v) return hb(p,1);
        pd(p);
        if (t[p].l==t[p].r){
            t[p].w=ne[t[p].w];t[p].v=f[t[p].w];
            if (t[p].v) for (t[p].b[0]=t[p].w,t[p].le=1,i=ne[t[p].w];i!=t[p].w;i=ne[i]) t[p].b[t[p].le++]=i;
            return;
        }
        int mid=t[p].l+t[p].r>>1;
        if (r<=mid) ch(lp,l,r);else
        if (l>mid) ch(rp,l,r);else
        ch(lp,l,mid),ch(rp,mid+1,r);
        updata(p);
    }
    inline int MMH(int p,int l,int r){
        pd(p);
        if (t[p].l==l&&t[p].r==r) return t[p].w;
        int mid=t[p].l+t[p].r>>1;
        if (r<=mid) return MMH(lp,l,r);else
        if (l>mid) return MMH(rp,l,r);else
        return MMH(lp,l,mid)+MMH(rp,mid+1,r);
    }
    int main(){
        register int i,j,T,l,r;
        n=read();m=read();
        p=read();
        for (i=1;i<=n;i++) a[i]=read();
        for (i=0;i<p;i++) ne[i]=i*i%p,f[i]=1;
        for (i=0;i<p;i++)
        if (!v[i]){
            for (j=i;!v[j];j=ne[j]) v[j]=1;
            for (T=i;T!=j;T=ne[T]) f[T]=0;
        }
        build(1,1,n);
        for (i=1;i<=m;i++){
            T=read();l=read();r=read();
            if (T)printf("%d
    ",MMH(1,l,r));else ch(1,l,r);
        }
    }
    
    View Code
  • 相关阅读:
    (转)elasticsearch5.2.2 压测配置
    (转) Elasticsearch 5.0 安装 Search Guard 5 插件
    (转)设置Sysctl.conf用以提高Linux的性能(最完整的sysctl.conf优化方案)
    分布式搜索elasticsearch配置文件详解
    (转)ActiveMQ的重连机制
    (转)Linux 命令--查看物理CPU个数、核数、逻辑CPU个数
    哈佛大学凌晨4点半的景象
    (转)关于ActiveMQ的配置
    最大似然估计 (Maximum Likelihood Estimation), 交叉熵 (Cross Entropy) 与深度神经网络
    TensorFlow的开源与Hadoop的开源
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5510247.html
Copyright © 2011-2022 走看看