bzoj:4105: [Thu Summer Camp 2015]平方运算

Posted Swm_sxt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\\n",MMH(1,l,r));else ch(1,l,r);
    }
}
View Code

 

以上是关于bzoj:4105: [Thu Summer Camp 2015]平方运算的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ4896 [Thu Summer Camp2016]补退选

BZOJ 4104 4104: [Thu Summer Camp 2015]解密运算 (智商)

bzoj4896 [Thu Summer Camp2016]补退选

bzoj4104 [Thu Summer Camp 2015]解密运算

BZOJ 4896 :[Thu Summer Camp2016]补退选 Trie树+Vector

bzoj4896 [Thu Summer Camp2016]补退选