忠诚//线段树

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

输出格式

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

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

时间: 2024-11-05 21:00:10

忠诚//线段树的相关文章

tyvj:1038 忠诚 线段树

tyvj:1038 忠诚 Time Limit: 1 Sec  Memory Limit: 131072KiBSubmit: 9619  Solved: 3287 题目连接 http://www.tyvj.cn/p/1038 Description 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满 意.但是由于一些人的挑拨,财主还是对管家产生了怀疑.于是他决定用一种特别的方法来判断管家的忠诚,他把每次

回档|忠诚2|zkw线段树

线段树,大家一看就明白了吧,这题就是一模板题,我学zkw线段树用的.单点维护,区间最值. 题目是tyvj的忠诚2. #include"iostream" #include"cstdio" using namespace std; int M; int T[10000000]; int read() { char c=getchar(); int a=0; while (c<'0'||c>'9') c=getchar(); while (c>='0'

tyvj 1038 忠诚 区间最小值 线段树或者rmq

P1038 忠诚 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人的挑拨,财主还是对管家产生了怀疑.于是他决定用一种特别的方法来判断管家的忠诚,他把每次的账目按1,2,3…编号,然后不定时的问管家问题,问题是这样的:在a到b号账中最少的一笔是多少?为了让管家没时间作假他总是一次问多个问题. 输入

线段树——忠诚——洛谷——1816

本次的目的主要在于练一练线段树的模板. 这题做法颇多,可以RMQ也可以线段树 #include<iostream> #include<cstdio> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=n

[luoguP1816] 忠诚(RMQ || 线段树)

传送门 其实我就是想练练 rmq 本以为学了线段树可以省点事不学 rmq 了 但是后缀数组中用 rmq 貌似很方便 所以还是学了吧,反正也不难 ——代码 1 #include <cstdio> 2 #define N 100001 3 #define min(x, y) ((x) < (y) ? (x) : (y)) 4 5 int n, m; 6 int a[N], d[N][21]; 7 8 int main() 9 { 10 int i, j, k, x, y; 11 scanf(

HDU - 4366 Successor DFS序 + 分块暴力 or 线段树维护

给定一颗树,每个节点都有忠诚和能力两个参数,随意指定一个节点,要求在它的子树中找一个节点代替它,这个节点要满足能力值大于它,而且是忠诚度最高的那个. 首先,dfs一下,处理出L[i], R[i]表示dfs序,则R[i] - L[i] + 1 就是当前i这个节点拥有的子孙个数. 对于一颗树,dfs的时候,访问节点有先后顺序,那么可以用一个struct node List[maxn];表示这课树中访问的先后顺序. 例如这颗树,我假设是先访问0 --> 3 --> 2 ---> 4 ---&g

树状数组和线段树

一.树状数组 在解题过程中,我们有时需要维护一个数组的前缀和 S[i]=A[1]+A[2]+...+A[i] .但是不难发现,如果我们修改了任意一个 A[i],S[i] . S[i+1]...S[n] 都会发生变化.可以说,每次修改 A[i] 后,调整前缀和 S[] 在最坏情况下会需要 O(n) 的时间.当 n 非常大时,程序会运行得非常缓慢.因此,这里我们引入"树状数组",它的修改与求和都是 O(logn) 的,效率非常高. 实现: 对于正整数x,定义lowbit(x)为x的二进制表

HDU 4366 Successor( DFS序+ 线段树 )

Successor Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2631    Accepted Submission(s): 634 Problem Description Sean owns a company and he is the BOSS.The other Staff has one Superior.every st

线段树基操

P1816 忠诚 st表竟然写挂了,线段树一遍过(就当练码力) P1198 [JSOI2008]最大数 1.动态在末尾插入一个数 2.输出末尾的L个数的最大值 线段树维护! P3870 [TJOI2009]开关 P2574 XOR的艺术 P2846 [USACO08NOV]光开关Light Switching 三倍经验题!!! 对一段01区间取^1,则若要修改这个o,这段区间的1的个数=区间长度-这段区间的1的个数(t[o].yihuo) 对于一个o,是否修改这个区间,可以对t[o].tag^1