【P2879】 [USACO07JAN]區間統計Tallest Cow {前綴和,思維}
阿新 • • 發佈:2019-02-06
證明 pair 沒有 names 算法 int for 區間 algorithm
思路:
先初始化所有牛的身高為0。
對於每一個約束條件(a,b)我們將a+1 ~ b-1的牛的身高全部減一。
樸素的減是TLE的,所以我們維護一個前綴和數組d[]來搞,對於約束條件(a,b)我們將d[a+1]--,將d[b]++。
碎碎念:
這個思路很明白,但是為什麽是正確的(尤其是為什麽每次減一不會產生矛盾)?我把luogu的題解瀏覽了一遍也沒有看到證明。
所以我就自己證了一下。有兩種證明方法:
一是循環不變式(算法導論上有很漂亮的例子),證起來很清晰。
二是反證法:假設有一組約束條件必須減>=2才能夠滿足,可以導出矛盾。
這裏不展開證明,經過思考應當容易寫出。
code:
#include <iostream> #include <algorithm> #include <cstdio> #include <map> using namespace std; map<pair<int,int>,bool> existed; int c[10010],d[10010]; int main(){ int n,p,h,m; scanf("%d%d%d%d",&n,&p,&h,&m); for(int i = 1;i <= m;++i){ int a,b; scanf("%d%d",&a,&b); if(a > b)std::swap(a,b); if(existed[make_pair(a,b)])continue; d[a+1]--,d[b]++; existed[make_pair(a,b)] = true; } for(int i = 1;i <= n;++i){ c[i] = c[i-1]+d[i]; printf("%d\n",h+c[i]); } return 0; }
【P2879】 [USACO07JAN]區間統計Tallest Cow {前綴和,思維}