P1038 忠诚
时间: 1000ms / 空间: 131072KiB / Java类名: Main
描述
老管家是一个聪明能干的人。他为财主工作了整整10年,财主为了让自已账目更加清楚。要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意。但是由于一些人的挑拨,财主还是对管家产生了怀疑。于是他决定用一种特别的方法来判断管家的忠诚,他把每次的账目按1,2,3…编号,然后不定时的问管家问题,问题是这样的:在a到b号账中最少的一笔是多少?为了让管家没时间作假他总是一次问多个问题。
输入格式
输入中第一行有两个数m,n表示有m(m<=100000)笔账,n表示有n个问题,n<=100000。
第二行为m个数,分别是账目的钱数
后面n行分别是n个问题,每行有2个数字说明开始结束的账目编号。
输出格式
输出文件中为每个问题的答案。具体查看样例。
测试样例1
输入
10 3
1 2 3 4 5 6 7 8 9 10
2 7
3 9
1 10
输出
2 3 1
线段树教程:http://blog.csdn.net/metalseed/article/details/8039326
http://hzwer.com/670.html
http://www.cnblogs.com/gc812/p/5773903.html
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int n,q,a[100001]; 5 struct data{ 6 int min; 7 }node[400001]; 8 int Min(int x,int y) 9 { 10 if(x<y)return x; 11 else return y; 12 } 13 void build(int pos,int l,int r) 14 { 15 if(l==r){ 16 node[pos].min=a[l]; 17 return; 18 } 19 int mid=l+r>>1; 20 int lson=2*pos,rson=lson+1; 21 build(lson,l,mid); 22 build(rson,mid+1,r); 23 node[pos].min=node[pos*2].min>node[pos*2+1].min?node[pos*2+1].min:node[pos*2].min; 24 } 25 int query(int pos,int l,int r,int ql,int qr) { 26 if(l==ql&&r==qr)return node[pos].min; 27 int mid=l+r>>1,lson=pos*2,rson=pos*2+1; 28 if(qr<=mid)return query(lson,l,mid,ql,qr); 29 else if(ql>mid) return query(rson,mid+1,r,ql,qr); 30 else return Min(query(lson,l,mid,ql,mid),query(rson,mid+1,r,mid+1,qr)); 31 } 32 int main() 33 { 34 scanf("%d%d",&n,&q); 35 for(int i=1;i<=n;i++) 36 scanf("%d",&a[i]); 37 build(1,1,n); 38 for(int i=1;i<=q;i++) 39 { 40 int x,y; 41 scanf("%d%d",&x,&y); 42 printf("%d ",query(1,1,n,x,y)); 43 } 44 return 0; 45 }
P1039 忠诚2
时间: 1000ms / 空间: 131072KiB / Java类名: Main
描述
老管家是一个聪明能干的人。他为财主工作了整整10年,财主为了让自已账目更加清楚。要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意。但是由于一些人的挑拨,财主还是对管家产生了怀疑。于是他决定用一种特别的方法来判断管家的忠诚,他把每次的账目按1,2,3…编号,然后不定时的问管家问题,问题是这样的:在a到b号账中最少的一笔是多少?为了让管家没时间作假他总是一次问多个问题。
在询问过程中账本的内容可能会被修改
在询问过程中账本的内容可能会被修改
输入格式
输入中第一行有两个数m,n表示有m(m<=100000)笔账,n表示有n个问题,n<=100000。
接下来每行为3个数字,第一个p为数字1或数字2,第二个数为x,第三个数为y
当p=1 则查询x,y区间
当p=2 则改变第x个数为y
接下来每行为3个数字,第一个p为数字1或数字2,第二个数为x,第三个数为y
当p=1 则查询x,y区间
当p=2 则改变第x个数为y
输出格式
输出文件中为每个问题的答案。具体查看样例。
测试样例1
输入
10 3
1 2 3 4 5 6 7 8 9 10
1 2 7
2 2 0
1 1 10
输出
2 0
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int n,q,a[100001]; 5 struct data{ 6 int min; 7 }node[400001]; 8 int Min(int x,int y) 9 { 10 if(x<y)return x; 11 else return y; 12 } 13 void build(int pos,int l,int r) 14 { 15 if(l==r){ 16 node[pos].min=a[l]; 17 return; 18 } 19 int mid=l+r>>1; 20 int lson=2*pos,rson=lson+1; 21 build(lson,l,mid); 22 build(rson,mid+1,r); 23 node[pos].min=node[pos*2].min>node[pos*2+1].min?node[pos*2+1].min:node[pos*2].min; 24 } 25 int query(int pos,int l,int r,int ql,int qr) { 26 if(l==ql&&r==qr)return node[pos].min; 27 int mid=l+r>>1,lson=pos*2,rson=pos*2+1; 28 if(qr<=mid)return query(lson,l,mid,ql,qr); 29 else if(ql>mid) return query(rson,mid+1,r,ql,qr); 30 else return Min(query(lson,l,mid,ql,mid),query(rson,mid+1,r,mid+1,qr)); 31 } 32 int getpos(int pos,int l,int r,int m) { 33 if (l==r && l==m) 34 return pos; 35 int mid=l+r>>1; 36 if (m<=mid) 37 return getpos(pos*2,l,mid,m); 38 else 39 return getpos(pos*2+1,mid+1,r,m); 40 } 41 void modify_dot(int pos,int v,int n) { 42 node[pos].min=v; 43 while (pos!=1) { 44 if (pos%2==0) { //×ó 45 node[pos/2].min=node[pos+1].min<node[pos].min?node[pos+1].min:node[pos].min; 46 } else { //ÓÒ 47 node[pos/2].min=node[pos-1].min<node[pos].min?node[pos-1].min:node[pos].min; 48 } 49 pos=pos/2;//°Ö°Ö 50 } 51 return; 52 } 53 int main() 54 { 55 scanf("%d%d",&n,&q); 56 for(int i=1;i<=n;i++) 57 scanf("%d",&a[i]); 58 build(1,1,n); 59 for(int i=1;i<=q;i++) 60 { 61 int p,x,y; 62 scanf("%d%d%d",&p,&x,&y); 63 if(p==1){ 64 printf("%d ",query(1,1,n,x,y)); 65 } 66 if(p==2){ 67 int pos=getpos(1,1,n,x); 68 modify_dot(pos,y,n); 69 } 70 } 71 return 0; 72 }