记录编号 440415 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [thusc2015]平方运算 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 5.173 s
提交时间 2017-08-23 08:43:51 内存使用 13.28 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N=4e5+10;
int n,m,p,a[N],tp,l,r;
void vio(){
	while (m--){
		scanf("%d%d%d",&tp,&l,&r);
		if (tp==0)
			for (int i=l;i<=r;i++) a[i]=a[i]*a[i]%p;
		else{
			int ans=0;
			for (int i=l;i<=r;i++) ans+=a[i];
			printf("%d\n",ans);
		}
	}
}
int go[N],vis[N],len=1,num;
bool incir[N];
int gcd(int x,int y){return y?gcd(y,x%y):x;}
void init(){
	for (int i=0;i<p;i++) go[i]=i*i%p;
	for (int i=0;i<p;i++)
	if (!vis[i]){
		int x=i;
		for (x=i;!vis[x];x=go[x]) vis[x]=i+1;
		if (vis[x]!=i+1) continue;
		num++;
		int cnt=1,end=x;
		incir[x]=1;
		for (x=go[x];x!=end;x=go[x]) incir[x]=1,cnt++;
		len=len/gcd(len,cnt)*cnt;
	}
}
struct segment_tree{
	int id,now[N],tag[N];
	vector<int> list[N];
	bool not_in_cir[N];
	#define lc x<<1
	#define rc x<<1|1
	void move(int &x,int p){
		x+=p;
		if (x>=len) x-=len;
	}
	void update(int x){
		int p=now[x],pl=now[lc],pr=now[rc];
		for (int i=0;i<len;i++){
			list[x][p]=list[lc][pl]+list[rc][pr];
			move(p,1);move(pl,1);move(pr,1);
		}
		not_in_cir[x]=not_in_cir[lc]||not_in_cir[rc];
	}
	void add(int x,int p){
		move(now[x],p);
		move(tag[x],p);
	}
	void pushdown(int x){
		if (tag[x]){
			add(lc,tag[x]);
			add(rc,tag[x]);
			tag[x]=0;
		}
	}
	void newnode(int x,int val){
		not_in_cir[x]=!incir[val];
		for (int i=0;i<len;i++) list[x][i]=val,val=go[val];
	}
	void init(int x,int l,int r){
		now[x]=0;
		list[x].resize(len,0);
		if (l==r) return newnode(x,a[l]);
		int mid=(l+r)>>1;
		init(lc,l,mid);
		init(rc,mid+1,r);
		update(x);
	}
	void move(int x,int l,int r,int L,int R){
		if (l>=L&&r<=R&&!not_in_cir[x]) return add(x,1);
		if (l==r) return newnode(x,go[list[x][now[x]]]);
		pushdown(x);
		int mid=(l+r)>>1;
		if (L<=mid) move(lc,l,mid,L,R);
		if (R>mid) move(rc,mid+1,r,L,R);
		update(x);
	}
	int query(int x,int l,int r,int L,int R){
		if (l>=L&&r<=R) return list[x][now[x]];
		pushdown(x);
		int mid=(l+r)>>1,ans=0;
		if (L<=mid) ans+=query(lc,l,mid,L,R);
		if (R>mid) ans+=query(rc,mid+1,r,L,R);
		return ans;
	}
}T;
int main()
{
	freopen("thusc2015_square.in","r",stdin);
	freopen("thusc2015_square.out","w",stdout);
	scanf("%d%d%d",&n,&m,&p);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	//if (n*m<=1e8) vio();
	init();
	T.init(1,1,n);
	while (m--){
		scanf("%d%d%d",&tp,&l,&r);
		if (tp==0) T.move(1,1,n,l,r);else printf("%d\n",T.query(1,1,n,l,r));
	}
	return 0;
}