码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-05-19 23:05:40      阅读:852      评论:0      收藏:0      [点我收藏+]

标签:

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]平方运算

标签:

原文地址:http://www.cnblogs.com/Enceladus/p/5510247.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!