忠诚//线段树

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 }
View Code

 


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

输出格式

输出文件中为每个问题的答案。具体查看样例。

测试样例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 }
View Code

 

posted @ 2016-08-15 20:00  pandaB  阅读(311)  评论(0编辑  收藏  举报