记录编号 164875 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [thusc2015]平方运算 最终得分 100
用户昵称 GravatarAsm.Def 是否通过 通过
代码语言 C++ 运行时间 7.539 s
提交时间 2015-06-07 10:15:57 内存使用 115.60 MiB
显示代码纯文本
/***********************************************************************/
/**********************By Asm.Def-Wu Jiaxin*****************************/
/***********************************************************************/
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <algorithm>
using namespace std;
#define SetFile(x) ( freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout) );
#define UseFREAD
#ifdef UseFREAD
#define getc() *(file_ptr++)
#define FreadLenth 5000000
char CHARPOOL[FreadLenth], *file_ptr = CHARPOOL;
#else
#define getc() getchar() 
#endif
#ifdef DEBUG
#include <ctime>
#endif
template<class T>inline void getd(T &x){
	char ch = getc();bool neg = false;
	while(!isdigit(ch) && ch != '-')ch = getc();
	if(ch == '-')ch = getc(), neg = true;
	x = ch - '0';
	while(isdigit(ch = getc()))x = x * 10 - '0' + ch;
	if(neg)x = -x;
}
/***********************************************************************/
const int maxn = 100005;

inline int gcd(int a, int b){return (!a) ? b : gcd(b % a, a);}
inline int lcm(int a, int b){return a / gcd(a, b) * b;}

struct Data{
	Data *nxt;
	int Sum;
}DT[maxn << 7], *DTiter = DT;
inline void *operator new(size_t) {return DTiter++;}
inline void sh(Data *&x){x = x->nxt;}//shift

int N, A[maxn], p;
bool Ring[maxn], vis[maxn], onp[maxn];

struct SegT{
	int L, R, mid, tag, len;
	Data *dt;
	SegT *ls, *rs;
	inline void push(){
		tag %= len;
		if(ls){
			ls->tag += tag, rs->tag += tag;
			while(tag)sh(ls->dt), sh(rs->dt), --tag;
		}
		else tag = 0;
	}
	inline void update(){
		Data *it = dt, *l = ls->dt, *r = rs->dt;
		if(!len){it->Sum = l->Sum + r->Sum;return;}
		for(int i = 1;i <= len;++i, sh(it), sh(l), sh(r))
			it->Sum = l->Sum + r->Sum;
	}
	inline void init_dt(){
		Data *it = dt;
		int t = dt->Sum, x = t * t % p;
		for(len = 1;x != t;x = x * x % p){
			it = (it->nxt = new Data);
			it->Sum = x;
			++len;
		}
		it->nxt = dt;
		return;
	}
	inline void merge_dt(){
		Data *it = dt;
		Data *l = ls->dt, *r = rs->dt;
		len = lcm(ls->len, rs->len);
		it->Sum = l->Sum + r->Sum;
		sh(l), sh(r);
		for(int i = 1;i < len;++i, sh(l), sh(r)){
			it = (it->nxt = new Data);
			it->Sum = l->Sum + r->Sum;
		}
		it->nxt = dt;
	}
	inline void Modify(int l, int r){ 
		if(L == l && R == r){
			if(!len){
				if(L == mid){
					dt->Sum = dt->Sum * dt->Sum % p;
					if(Ring[dt->Sum])init_dt();
					return;
				}
				ls->Modify(l, mid), rs->Modify(mid, r);
				if(ls->len && rs->len)merge_dt();
				else dt->Sum = ls->dt->Sum + rs->dt->Sum;
				return;
			}
			sh(dt);
			++tag;
			return;
		}
		if(tag)push();
		if(r <= mid)ls->Modify(l, r);
		else if(l >= mid)rs->Modify(l, r);
		else ls->Modify(l, mid), rs->Modify(mid, r);
		update();
	}
	inline int Query(int l, int r){
		if(L == l && R == r)return dt->Sum;
		if(tag)push();
		if(r <= mid)return ls->Query(l, r);
		if(l >= mid)return rs->Query(l, r);
		return ls->Query(l, mid) + rs->Query(mid, r);
	}
	inline void init(int, int);
}seg, Pool[maxn << 2], *iter = Pool;

inline void SegT::init(int l, int r){
	L = l, R = r, mid = (l + r) >> 1;
	tag = 0;
	dt = new Data;
	if(L == mid){
		len = 0;
		dt->Sum = A[L];
		if(Ring[A[L]])init_dt();
		return;
	}
	ls = iter++, rs = iter++;
	ls->init(l, mid), rs->init(mid, r);
	update();
}

inline void find(int x){
	onp[x] = vis[x] = true;
	int t = x * x % p;
	if(onp[t]){
		while(t != x)Ring[t] = true, t = t * t % p;
		Ring[x] = true;
		onp[x] = false;
		return;
	}
	if(!vis[t])find(t);
	onp[x] = false;
}

inline void work(){
	int M, opt, l, r;
	getd(N), getd(M), getd(p);
	for(int i = 1;i <= N;++i)getd(A[i]);
	for(int i = 1;i <= N;++i)if(!vis[A[i]])find(A[i]);
	seg.init(1, N+1);

	//for(int i = 0;i < p;++i)printf("%d ", Ring[i]);
	while(M--){
		getd(opt), getd(l), getd(r);
		if(opt)printf("%d\n", seg.Query(l, r+1));
		else seg.Modify(l, r+1);
	}
}

int main(){

#ifdef DEBUG
	freopen("test.txt", "r", stdin);
#elif !defined ONLINE_JUDGE
	SetFile(thusc2015_square);
#endif

#ifdef UseFREAD
	fread(file_ptr, 1, FreadLenth, stdin);
#endif
	work();

#ifdef DEBUG
	printf("\n%.3lf sec \n", (double)clock() / CLOCKS_PER_SEC);
#endif
	return 0;
}