忠诚
题目描述
老管家是一个聪明能干的人。他为财主工作了一整整 10 年,财主为了让自己的账目更清楚。要求管家每天记住 k 因为管家聪明能干,管家总是让财主满意。然而,由于一些人的挑衅,财主仍然怀疑管家。因此,他决定用一种特殊的方法来判断管家的忠诚度。他按每个账户 1,2,3… 编号,然后不时问管家问题,问题是:在 a 到 b 账户中最少的一笔是多少?他总是问很多问题,让管家没有时间作弊。
在询问过程中,可能会修改帐簿的内容
输入
第一行输入有两个数字 m;n 表示有 m(m≤100000) 笔账 ,n 表示有 n 个问题,n≤100000。 接下来的每一个行为 3 数字,第一个 p 为数字 1 或数字 二、二是数 x,第三个数为 y。 当 p=1 则查询 x;y 区间 当 p=2 则改变第 x 个数为 y
输出
每个问题的答案都在输出文件中。详见样例。
样例
in
10 3 1 2 3 4 5 6 7 8 9 10 1 2 7 2 2 0 1 1 10
out
2 0
解法
这个为线段树模板题,可创建修改单点和查询区间函数
代码
#include<bits/stdc .h> using namespace std; int n,m,sum[400010],a[400010]; int p(int x){ sum[x] = min(sum[x*2],sum[x*2 1]); } // 初始化函数 void b(int l,int r,int rt){ if(l==r){ sum[rt] = a[l];return ; } int mid = l r>>1; b(l,mid,rt*2); b(mid 1,r,rt*2 1); p(rt); } // 修改函数 void xx(int l,int r,int rt,int x,int d){ if(l==r){ sum[rt] = d; return ; } int mid = l r>>1; if( x<=mid) xx(l,mid,rt*2,x,d); else xx(mid 1,r,rt*2 1,x,d); p(rt); } // 查询区间 int c(int l,int r,int rt,int x,int y){ if(l>=x and y>=r){ return sum[rt]; } int mid = l r>>1; int ans=1234567890; if(x<=mid){ ans = min(ans,c(l,mid,rt*2,x,y)); } if(y>mid){ ans = min(ans,c(mid 1,r,rt*2 1,x,y)); } return ans; } int main(){ cin >> n >> m; // 输入 for(int i=1;i<=n;i ){ cin >> a[i]; } b(1,n,1); // 初始化 for(int i=1;i<=m;i ){ // 遍历每一个问题 int p,x,y; cin >> p >> x >> y; if(p==1){ cout << c(1,n,1,x,y) << ' '; }else{ xx(1,n,1,x,y); } } return 0; }
感谢观看 欢迎加入我和朋友创建的域!