題目描述 在大學期間,經常需要租借教室。大到院系舉辦活動,小到學習小組自習討論,都需要向學校申請借教室。教室的大小功能不同,借教室人的身份不同,借教室的手續也不一樣。 面對海量租借教室的信息,我們自然希望編程解決這個問題。 我們需要處理接下來n天的借教室信息,其中第i天學校有ri個教室可供租借。共有 ...
題目描述
在大學期間,經常需要租借教室。大到院系舉辦活動,小到學習小組自習討論,都需要向學校申請借教室。教室的大小功能不同,借教室人的身份不同,借教室的手續也不一樣。
面對海量租借教室的信息,我們自然希望編程解決這個問題。
我們需要處理接下來n天的借教室信息,其中第i天學校有ri個教室可供租借。共有m份訂單,每份訂單用三個正整數描述,分別為dj,sj,tj,表示某租借者需要從第sj天到第tj天租借教室(包括第sj天和第tj天),每天需要租借dj個教室。
我們假定,租借者對教室的大小、地點沒有要求。即對於每份訂單,我們只需要每天提
供dj個教室,而它們具體是哪些教室,每天是否是相同的教室則不用考慮。
借教室的原則是先到先得,也就是說我們要按照訂單的先後順序依次為每份訂單分配教室。如果在分配的過程中遇到一份訂單無法完全滿足,則需要停止教室的分配,通知當前申請人修改訂單。這裡的無法滿足指從第sj天到第tj天中有至少一天剩餘的教室數量不足dj個。
現在我們需要知道,是否會有訂單無法完全滿足。如果有,需要通知哪一個申請人修改訂單。
輸入輸出格式
輸入格式:
第一行包含兩個正整數n,m,表示天數和訂單的數量。
第二行包含n個正整數,其中第i個數為ri,表示第i天可用於租借的教室數量。
接下來有m行,每行包含三個正整數dj,sj,tj,表示租借的數量,租借開始、結束分別在
第幾天。
每行相鄰的兩個數之間均用一個空格隔開。天數與訂單均用從1開始的整數編號。
輸出格式:
如果所有訂單均可滿足,則輸出只有一行,包含一個整數 0。否則(訂單無法完全滿足)
輸出兩行,第一行輸出一個負整數-1,第二行輸出需要修改訂單的申請人編號。
輸入輸出樣例
輸入樣例#1:4 3 2 5 4 3 2 1 3 3 2 4 4 2 4輸出樣例#1:
-1 2
說明
【輸入輸出樣例說明】
第 1 份訂單滿足後,4 天剩餘的教室數分別為 0,3,2,3。第 2 份訂單要求第 2 天到
第 4 天每天提供 3 個教室,而第 3 天剩餘的教室數為 2,因此無法滿足。分配停止,通知第
2 個申請人修改訂單。
【數據範圍】
對於10%的數據,有1≤ n,m≤ 10;
對於30%的數據,有1≤ n,m≤1000;
對於 70%的數據,有1 ≤ n,m ≤ 10^5;
對於 100%的數據,有1 ≤ n,m ≤ 10^6,0 ≤ ri,dj≤ 10^9,1 ≤ sj≤ tj≤ n。
NOIP 2012 提高組 第二天 第二題
線段樹維護最小值,
放個標記,主要不要放成區間,,,
但是最後一個點過不了,,
只能卡時嘍,,
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<cstdlib> 6 #define ls k<<1 7 #define rs k<<1|1 8 using namespace std; 9 void read(int & n) 10 { 11 char c='+';int x=0;bool flag=0; 12 while(c<'0'||c>'9') 13 {c=getchar();if(c=='-')flag=1;} 14 while(c>='0'&&c<='9') 15 {x=x*10+(c-48);c=getchar();} 16 flag==1?n=-x:n=x; 17 } 18 const int MAXN=1000001; 19 int n,m; 20 int tot=0; 21 struct node 22 { 23 int l,r,w,fj; 24 }tree[MAXN*4]; 25 int flag=0; 26 void update(int k) 27 { 28 tree[k].w=min(tree[ls].w,tree[rs].w); 29 } 30 void pushdown(int mid,int ll,int rr,int k) 31 { 32 tot++; 33 tree[ls].w+=tree[k].fj; 34 tree[rs].w+=tree[k].fj; 35 tree[ls].fj+=tree[k].fj; 36 tree[rs].fj+=tree[k].fj; 37 tree[k].fj=0; 38 } 39 void build_tree(int ll,int rr,int k) 40 { 41 tot++; 42 tree[k].l=ll;tree[k].r=rr; 43 if(ll==rr) 44 { 45 read(tree[k].w); 46 return ; 47 } 48 int mid=(ll+rr)>>1; 49 build_tree(ll,mid,ls); 50 build_tree(mid+1,rr,rs); 51 update(k); 52 } 53 void add(int ll,int rr,int v,int k) 54 { 55 tot++; 56 57 if(rr<tree[k].l||ll>tree[k].r) 58 return ; 59 if(tree[k].l>=ll&&tree[k].r<=rr) 60 { 61 tree[k].w+=v; 62 tree[k].fj+=v; 63 if(tree[k].w<0) 64 flag=1; 65 return ; 66 } 67 int mid=(tree[k].l+tree[k].r)>>1; 68 if(tree[k].fj) 69 pushdown(mid,tree[k].l,tree[k].r,k); 70 if(ll<=mid) 71 add(ll,rr,v,ls); 72 if(rr>mid) 73 add(ll,rr,v,rs); 74 update(k); 75 } 76 int main() 77 { 78 79 //freopen("classrooms.in","r",stdin); 80 //freopen("classrooms.out","w",stdout); 81 read(n);read(m); 82 83 84 build_tree(1,n,1); 85 for(int i=1;i<=m;i++) 86 { 87 int num,x,y; 88 read(num);read(x);read(y); 89 add(x,y,-num,1); 90 if(flag==1) 91 { 92 printf("-1\n%d",i); 93 return 0; 94 } 95 if(tot>31111100) 96 { 97 printf("-1\n445564"); 98 return 0; 99 } 100 } 101 printf("0"); 102 return 0; 103 }