18寒假第六測
阿新 • • 發佈:2018-02-12
格子 bound mage spa query 標記 std image build
第一題:乘法修改的線段樹
一定不能將change,modify分類討論定兩個標記,會有順序影響
lazy標記一定要long long,又忘了。。。
代碼和上一次差不多
第二題:離散暴力,也可以掃描線
離散時要將格子映射成點,不然會出現以下情況:
算橫著的小矩形寬就是2,算黃色面積寬還是2,因為沒有2讓3去減
如果映射成點,就像這樣,,放圖比較好理解,就像掃描線,一個葉子節點存的是一個左閉右開的區間
也可以離散+掃描線,但還沒寫出來
#include <bits/stdc++.h> using namespace std; #define maxn 1005 intdisx[maxn*2],disy[maxn*2],xs[maxn*2],xe[maxn*2],ys[maxn*2],ye[maxn*2]; int totx,toty; bool st[maxn*2][maxn*2]; void read(int &x){ int f=1;x=0;char s=getchar(); while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();} while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();} x*=f; }int main() { freopen("area.in","r",stdin); freopen("area.out","w",stdout); int n; read(n); for(int i = 1; i <= n; i++){ read(xs[i]),read(ys[i]),read(xe[i]),read(ye[i]); xs[i]-=1,ys[i]-=1; disx[++totx]=xs[i],disx[++totx]=xe[i]; disy[++toty]=ys[i],disy[++toty]=ye[i]; } sort(disx+ 1, disx + 1 + totx); sort(disy + 1, disy + 1 + toty); totx = unique(disx + 1, disx + 1 + totx) - disx - 1; toty = unique(disy + 1, disy + 1 + toty) - disy - 1; for(int k = 1; k <= n; k++){ int xn = lower_bound(disx + 1, disx + 1 + totx, xs[k]) - disx; int xm = lower_bound(disx + 1, disx + 1 + totx, xe[k]) - disx; int yn = lower_bound(disy + 1, disy + 1 + toty, ys[k]) - disy; int ym = lower_bound(disy + 1, disy + 1 + toty, ye[k]) - disy; for(int i = xn+1; i <= xm; i++) for(int j = yn+1; j <= ym; j++) st[i][j] = 1; } long long ans = 0; for(int i = 1; i <= totx; i++) for(int j = 1; j <= toty; j++) if(st[i][j]) ans += 1LL * (disx[i] - disx[i - 1]) * (disy[j] - disy[j - 1]); printf("%I64d\n",ans); return 0; }
第三題:可持久化數組,每次建樹logN的空間復雜度,不改變原來的版本
pool大小為N*2+Q*logN,Q為詢問次數
#include <bits/stdc++.h> using namespace std; #define maxn 100005 #define ll long long int a[maxn],n,m,s; void read(int &x){ int f=1;x=0;char s=getchar(); while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();} while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();} x*=f; } struct Node{ int v; Node *ls, *rs; }pool[maxn * 32],*tail = pool, *root[maxn];//? Node * build(int l = 1,int r = n){ Node *nd = ++tail; if(l == r) nd->v = a[l]; else { int m = (l + r) >> 1; nd->ls = build(l, m); nd->rs = build(m + 1, r); } return nd; } #define Ls nd->ls, l, m #define Rs nd->rs, m+1, r Node * modify(int delta, int pos, Node *nd, int l = 1, int r = n){ Node *nnd = ++tail; if(l == r) nnd->v = delta; else { int m = (l + r) >> 1; if(pos <= m){ nnd->rs = nd->rs; nnd->ls = modify(delta, pos, Ls); } if(pos > m){ nnd->ls = nd->ls; nnd->rs = modify(delta, pos, Rs); } } return nnd; } int query(int pos, Node *nd, int l = 1, int r = n ){ if(l == r) return nd->v; else { int m = (l + r) >> 1; if(pos <= m)return query(pos, Ls); else return query(pos, Rs); } } Node * print(int pos,Node *nd){ printf("%d\n",query(pos,nd)); return nd; } int main(){ freopen("array.in","r",stdin); freopen("array.out","w",stdout); read(n); for(int i = 1; i <= n; i++) read(a[i]); root[0] = build(); read(m); for(int i = 1; i <= m; i++){ string opt; cin>>opt; if(opt[0] == ‘q‘){ int pos; read(pos); root[i] = print(pos, root[i - 1]); } else if(opt[0] == ‘m‘){ int pos, x; read(pos), read(x); root[i] = modify(x,pos,root[i - 1]); } else { int t; read(t); root[i] = root[t]; } } }
18寒假第六測