1. 程式人生 > >P1816 忠誠

P1816 忠誠

struct clu mat tro 方法 mes 結束 art str

題目描述

老管家是一個聰明能幹的人。他為財主工作了整整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
輸出樣例#1:
2 3 1

註意這題在updata的時候一定要取最小值

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 const int
MAXN=1000001; 7 int n,m; 8 struct node 9 { 10 int l,r,f,w; 11 }tree[MAXN<<2]; 12 int read(int &x) 13 { 14 int flag=0; 15 char c=getchar();x=0; 16 if(c==-)flag=1; 17 while(c<0||c>9)c=getchar(); 18 while(c>=0&&c<=9)x=x*10+c-48,c=getchar();
19 return flag==1?-x:x; 20 } 21 void updata(int k) 22 { 23 tree[k].w=min(tree[k<<1].w,tree[k<<1|1].w); 24 } 25 void Build_Tree(int ll,int rr,int k) 26 { 27 tree[k].l=ll;tree[k].r=rr; 28 if(tree[k].l==tree[k].r) 29 { 30 read(tree[k].w); 31 return ; 32 } 33 int m=(ll+rr)>>1; 34 Build_Tree(ll,m,k<<1); 35 Build_Tree(m+1,rr,k<<1|1); 36 updata(k); 37 } 38 int interval_ask(int ll,int rr,int k) 39 { 40 if(ll<=tree[k].l&&rr>=tree[k].r) 41 return tree[k].w; 42 int ans=0x7fffff; 43 //if(tree[k].l==tree[k].r) 44 // return tree[k].w<ans?ans=tree[k].w:ans=ans; 45 int m=(tree[k].l+tree[k].r)>>1; 46 if(ll<=m) 47 ans=min(interval_ask(ll,rr,k<<1),ans); 48 if(rr>=m+1) 49 ans=min(interval_ask(ll,rr,k<<1|1),ans); 50 return ans; 51 } 52 int main() 53 { 54 read(n);read(m); 55 Build_Tree(1,n,1); 56 for(int i=1;i<=m;i++) 57 { 58 int x,y; 59 read(x);read(y); 60 printf("%d ",interval_ask(x,y,1)); 61 } 62 return 0; 63 }



P1816 忠誠