单点更新+区间求最值与和_线段树
来源:互联网 发布:linux vi 设置行号 编辑:程序博客网 时间:2024/04/29 17:02
除了平时做练习赛外,现在主要学习数论与数据结构,数据结构丢了好久了,重新学习还是发现了很多问题!
/*
题意:在每个测试的第一行,是两个正整数 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 __int64struct 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);elsechange(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;}
- 单点更新+区间求最值与和_线段树
- hdu_1166_线段树_单点更新_区间求和
- 线段树求区间和(单点更新)
- 线段树单点更新和区间查询
- 线段树 单点更新求区间和
- 线段树单点更新 区间求和,求最值
- 线段树_单点更新
- 线段树(单点更新+区间更新)
- 线段树 --- 单点更新,维护区间和,模板
- 线段树 的单点更新和区间求和
- hdu 1166 线段树单点更新和区间求和
- 线段树总结(单点更新,区间更新,区间求和,区间求最值)
- 12299 - RMQ with Shifts(线段树单点更新、区间求最值)
- zoj (单点更新区间查询:线段树)
- 线段树(单点更新,区间求和)
- hdu1166(线段树单点更新区间查询)
- poj2352Stars【线段树单点更新区间求和】
- leetCode_线段树、单点更新、区间求和
- NSButtonCell inside custom NSCell
- 设计模式学习
- ICE异常处理
- Windows上Emacs的安装及emacsclient进行C/S连接
- C++ 构造函数 析构函数 虚函数
- 单点更新+区间求最值与和_线段树
- 系统在处理一些 I/O 事件或磁盘读取时会动态提升相应线程的优先级
- 程序员修炼之道-定期为你的资产投资
- Linux的scp命令
- 关于siverlight程序发布的问题。
- ios:新浪微博iphone客户端
- Android音频实时传输与播放(一):写在开头
- [JavaScript] 对象字面量与JSON的区别
- HTTP协议详解