Noip2012-借教室
阿新 • • 發佈:2018-11-06
這個題首先很容易想到列舉1-m,再一個一個加起來,判斷一下(最直白的暴力)
於是又很容易想到用差分陣列可以優化一下。
就像這樣
#include <iostream> #include <cstdio> using namespace std; const int maxn=1000005; int d[maxn],s[maxn],t[maxn],r[maxn]; int c[maxn];int n,m; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&r[i]); for(int i=1;i<=m;i++) { scanf("%d%d%d",&d[i],&s[i],&t[i]); } for(int i=1;i<=m;i++) { c[s[i]]+=d[i];c[t[i]+1]-=d[i]; int sum=0; for(int j=1;j<=n;j++) { sum+=c[j];if(sum>r[j]) {cout<<"-1"<<endl<<i<<endl;return 0;} } } cout<<0<<endl; return 0; }
然而這樣只有40分。。。
我們又發現外層循換i=1-m是滿足單調性的
SO,可以二分一下x(x是指1-x都滿足條件)
就很愉快的ac了
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn=1000005; int d[maxn],s[maxn],t[maxn],r[maxn]; int c[maxn];int n,m; int ok(int x) { memset(c,0,sizeof(c)); for(int i=1;i<=x;i++) { c[s[i]]+=d[i];c[t[i]+1]-=d[i]; } int sum=0; for(int i=1;i<=n;i++) { sum+=c[i];if(sum>r[i]) return 0; } return 1; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&r[i]); for(int i=1;i<=m;i++) { scanf("%d%d%d",&d[i],&s[i],&t[i]); } int l=0,r=m;int ans=-1; while(l<=r) { int mid=(l+r)/2; if(ok(mid)) {ans=mid;l=mid+1;} else r=mid-1; } //printf("%d",ans); if(ans==m) {printf("%d\n",0);} else {printf("-1\n%d",ans+1);} return 0; }