紀中暑假集訓 2020.08.13【NOIP提高組】模擬 T4:【GDKOI2014】【GDKOI2014】記憶體分配
阿新 • • 發佈:2020-08-13
Description
Input
Output
輸出m行,每行一個整數,代表輸入中每次程式變化後系統所需要的空閒記憶體單位數。
Sample Input
2 3
1 4
1 4
2 2 1
2 1 1
1 1 1
Sample Output
2
3
1
Data Constraint
對於30%的資料,有1<=n,m<=1000
對於100%的資料,有1<=n,m<=100000
Hint
反思&題解
比賽思路: 沒認真看題,沒看懂……
正解思路: 很顯然是線段樹 (顯然嗎?為啥別人一眼就看出來?) ,設\(sum[l][r]\)表示\(\sum^{r}_{i=l}a[i]\)
\(ans[l][r]=max(ans[l][mid-1],ans[mid+1][r]-sum[l,m])\)
又因為是線段樹,所以這兩個陣列直接開一維就行了
反思: 需要加強一下線段樹這個弱項
CODE
#include<bits/stdc++.h> using namespace std; const long long inf=1000000000; struct arr { long long lson,rson,x,num; }tree[4000005]; long long n,m,a[1000005],b[1000005],tot,ans[4000005]; void change(long long now,long long l,long long r,long long aa,long long bb) { if (l==r) { tree[now].x+=aa; tree[now].num++; ans[now]=bb; } else { long long mid=l+r>>1; if (bb<=mid) { if (tree[now].lson==0) tree[now].lson=++tot; change(tree[now].lson,l,mid,aa,bb); } else { if (tree[now].rson==0) tree[now].rson=++tot; change(tree[now].rson,mid+1,r,aa,bb); } tree[now].x=tree[tree[now].lson].x+tree[tree[now].rson].x; if (ans[tree[now].lson]>=ans[tree[now].rson]-tree[tree[now].lson].x) ans[now]=ans[tree[now].lson]; else ans[now]=ans[tree[now].rson]-tree[tree[now].lson].x; } } void dele(long long now,long long l,long long r,long long aa,long long bb) { if (l==r) { tree[now].x-=aa; tree[now].num--; if (tree[now].num==0) ans[now]=0; } else { long long mid=l+r>>1; if (bb<=mid) { if (tree[now].lson==0) tree[now].lson=++tot; dele(tree[now].lson,l,mid,aa,bb); } else { if (tree[now].rson==0) tree[now].rson=++tot; dele(tree[now].rson,mid+1,r,aa,bb); } tree[now].x=tree[tree[now].lson].x+tree[tree[now].rson].x; if (ans[tree[now].lson]>=ans[tree[now].rson]-tree[tree[now].lson].x) ans[now]=ans[tree[now].lson]; else ans[now]=ans[tree[now].rson]-tree[tree[now].lson].x; } } int main() { scanf("%lld%lld",&n,&m); tot=1; long long i; for (i=1;i<=n;i++) { scanf("%lld%lld",&a[i],&b[i]); change(1,0,inf,a[i],b[i]); } while (m--) { long long j; scanf("%lld",&j); dele(1,0,inf,a[j],b[j]); scanf("%lld%lld",&a[j],&b[j]); change(1,0,inf,a[j],b[j]); printf("%lld\n",ans[1]); } return 0; }