除了平时做练习赛外,现在主要学习数论与数据结构,数据结构丢了好久了,重新学习还是发现了很多问题!
/*
题意:在每个测试的第一行,是两个正整数 N 和 M ( 0< N <= 100000, 0 < M <= 100000 ),分别代表学生的数目和操作的数目。
学生ID编号分别从 1 编到 N。第二行包含 N 个整数(范围在 0 到 100 ),代表这 N 个学生的初始成绩,其中第 i 个数代表 ID 为 i 的学生的成绩。
接下来有 M 行,每行有三个数,意思如下:
先输入一个数X,然后分两种情况:【1】【2】 (1 <= X <= 2^31-1)
【1】若X^X%999997是一个素数,则再输入两个数a,b,
意思是将ID为 a 的学生的成绩更新成b (1 <= a <= N, 0 <= b <= 100)
【2】若X^X%999997不是一个素数,则再输入两个数le,ri,
意思是输出区间【le,ri】中的学生的最低成绩、最高成绩、成绩总和 (1 <= le <= ri <= N)
Sample Input
2 8
69 24
131744484 1 1
598487296 2 2
542004961 2 2
241081 1 2
23299929 2 36
213276816 1 2
85264 1 2
350288656 1 2
Sample Output
69 69 69
24 24 24
24 24 24
24 69 93
36 69 105
36 69 105
36 69 105
Hint
【特别说明】
【1】在本题中,我们认为0和1也是素数!!!!
*/
#include<stdio.h>
#include<string.h>
using namespace std;
#define maxn 100005
#define maxn1 1000005
#define mod 999997
#define LL __int64
struct data
{
int l,r,minp,maxp,sump;
} tree[3*maxn];
int a[maxn];
bool prime[maxn1];
int min(int p,int q) { return p<q?p:q; }
int max(int p,int q) { return p>q?p:q; }
void Init()
{
int i,tmp;
memset(prime,false,sizeof(prime));
for(i=2;i<maxn1;i++)
if(!prime[i])
{
tmp=i*2;
while(tmp<maxn1)
{
prime[tmp]=true;
tmp+=i;
}
}
}
LL MOD(int a,int r)
{
LL d=1,t=(LL)a;
while(r)
{
if(r%2) d=(d*t)%mod;
r/=2;
t=t*t%mod;
}
return d%mod;
}
void BuildTree(int p,int l,int r)
{
tree[p].l=l,tree[p].r=r;
if(l==r)
{
tree[p].minp=tree[p].maxp=tree[p].sump=a[l];
return;
}
int mid=(l+r)>>1;
BuildTree(p<<1,l,mid);
BuildTree(p<<1|1,mid+1,r);
tree[p].minp=min(tree[p<<1].minp,tree[p<<1|1].minp);
tree[p].maxp=max(tree[p<<1].maxp,tree[p<<1|1].maxp);
tree[p].sump=tree[p<<1].sump+tree[p<<1|1].sump;
}
void change(int p,int i,int x)
{
if(tree[p].l==tree[p].r)
{
tree[p].minp=tree[p].maxp=tree[p].sump=x;
return;
}
if(i<=tree[p<<1].r)
change(p<<1,i,x);
else
change(p<<1|1,i,x);
tree[p].minp=min(tree[p<<1].minp,tree[p<<1|1].minp);
tree[p].maxp=max(tree[p<<1].maxp,tree[p<<1|1].maxp);
tree[p].sump=tree[p<<1].sump+tree[p<<1|1].sump;
}
data query(int p,int l,int r)
{
if(tree[p].l==l&&tree[p].r==r)
return tree[p];
if(r<=tree[p<<1].r)
return query(p<<1,l,r);
if(l>=tree[p<<1|1].l)
return query(p<<1|1,l,r);
int mid=(tree[p].l+tree[p].r)>>1;
data a=query(p<<1,l,mid),b=query(p>>1,mid+1,r);
a.sump+=b.sump;
a.minp=min(a.minp,b.minp);
a.maxp=max(a.maxp,b.maxp);
return a;
}
int main()
{
Init();
int n,m,i,id,x,y;
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
BuildTree(1,1,n);
while(m--)
{
scanf("%d%d%d",&id,&x,&y);
if(!prime[MOD(id,id)]) //对x^x%mod做素数判断
change(1,x,y);
else
{
data ans;
ans=query(1,x,y);
printf("%d %d %d\n",ans.minp,ans.maxp,ans.sump);
}
}
}
return 0;
}