【BZOJ4822】 [Cqoi2017]老C的任务

xiaoxiao2021-02-28  66

此题本来是一个很好的二维线段树模板题,然而居然卡空间(至少洛谷上是的)。

以下是二维线段树写法(大概70分):

#include <bits/stdc++.h> #define gc getchar() #define N 100009 #define M 16000009 #define mp make_pair #define pb push_back #define sz(x) (int)x.size() #define root 1,1,MaxN #define Root rt[cur],1,MaxM #define NOW int cur,int l,int r #define Now int &cur,int l,int r #define mid (l+r>>1) #define lc cur<<1 #define rc lc|1 #define lson lc,l,mid #define rson rc,mid+1,r #define Lson ls[cur],l,mid #define Rson rs[cur],mid+1,r #define ll long long using namespace std; ll p[N],sum[M]; int n,m,x[N],y[N],MaxN,MaxM,rt[N<<2],ls[M],rs[M],cnt; vector<int> X,Y; int read() { char ch; int x=1; while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1; int s=ch-'0'; while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0'; return s*x; } void Ins(Now,int y,ll p) { if (!cur) cur=++cnt; sum[cur]+=p; if (l==r) return; if (y<=mid) Ins(Lson,y,p); else Ins(Rson,y,p); } void ins(NOW,int x,int y,ll p) { Ins(Root,y,p); if (l==r) return; if (x<=mid) ins(lson,x,y,p); else ins(rson,x,y,p); } ll Qry(Now,int L,int R) { if (!cur) return 0; if (L<=l&&R>=r) return sum[cur]; ll ans=0; if (L<=mid) ans+=Qry(Lson,L,R); if (R>mid) ans+=Qry(Rson,L,R); return ans; } ll qry(NOW,int l1,int r1,int l2,int r2) { if (l1>r1||l2>r2||r1==0||r2==0||l1==MaxN+1||l2==MaxM+1) return 0ll; if (l1<=l&&r1>=r) return Qry(Root,l2,r2); ll ans=0; if (l1<=mid) ans+=qry(lson,l1,r1,l2,r2); if (r1>mid) ans+=qry(rson,l1,r1,l2,r2); return ans; } int main() { n=read(),m=read(); for (int i=1;i<=n;i++) { x[i]=read(),y[i]=read(),p[i]=read(); X.pb(x[i]),Y.pb(y[i]); } sort(X.begin(),X.end()); sort(Y.begin(),Y.end()); X.erase(unique(X.begin(),X.end()),X.end()); Y.erase(unique(Y.begin(),Y.end()),Y.end()); MaxN=sz(X),MaxM=sz(Y); for (int i=1;i<=n;i++) { x[i]=lower_bound(X.begin(),X.end(),x[i])-X.begin()+1; y[i]=lower_bound(Y.begin(),Y.end(),y[i])-Y.begin()+1; ins(root,x[i],y[i],p[i]); } for (int i=1;i<=m;i++) { int x1=read(),y1=read(),x2=read(),y2=read(); x1=lower_bound(X.begin(),X.end(),x1)-X.begin()+1; y1=lower_bound(Y.begin(),Y.end(),y1)-Y.begin()+1; x2=upper_bound(X.begin(),X.end(),x2)-X.begin(); y2=upper_bound(Y.begin(),Y.end(),y2)-Y.begin(); printf("%lld\n",qry(root,x1,x2,y1,y2)); } return 0; }然后另外一种显然就是离线拆询问+扫描线+树状数组啦:

#include <bits/stdc++.h> #define gc getchar() #define N 100009 #define M 16000009 #define mp make_pair #define pb push_back #define sz(x) (int)x.size() #define root 1,1,MaxN #define Root rt[cur],1,MaxM #define NOW int cur,int l,int r #define Now int &cur,int l,int r #define mid (l+r>>1) #define lc cur<<1 #define rc lc|1 #define lson lc,l,mid #define rson rc,mid+1,r #define Lson ls[cur],l,mid #define Rson rs[cur],mid+1,r #define ll long long using namespace std; ll p[N],sum[M],ans[N]; int n,m,x[N],y[N],MaxN,MaxM,cnt; vector<int> X,Y; struct coordinate { int x,y; ll p; coordinate(int x=0,int y=0,ll p=0):x(x),y(y),p(p){} }point[N]; bool operator <(const coordinate &a,const coordinate &b) { return a.x<b.x; } struct node { int x,l,r,pos; node(int x=0,int l=0,int r=0,int pos=0):x(x),l(l),r(r),pos(pos){} }q[N<<1]; bool operator <(const node &a,const node &b) { return a.x<b.x; } int read() { char ch; int x=1; while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1; int s=ch-'0'; while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0'; return s*x; } int lowbit(int x) { return x&(-x); } void add(int x,ll y) { for (;x<=n;x+=lowbit(x)) sum[x]+=y; } ll qry(int x) { ll ans=0; for (;x;x-=lowbit(x)) ans+=sum[x]; return ans; } int main() { n=read(),m=read(); for (int i=1;i<=n;i++) { x[i]=read(),y[i]=read(),p[i]=read(); X.pb(x[i]),Y.pb(y[i]); } sort(X.begin(),X.end()); sort(Y.begin(),Y.end()); X.erase(unique(X.begin(),X.end()),X.end()); Y.erase(unique(Y.begin(),Y.end()),Y.end()); MaxN=sz(X),MaxM=sz(Y); for (int i=1;i<=n;i++) { x[i]=lower_bound(X.begin(),X.end(),x[i])-X.begin()+1; y[i]=lower_bound(Y.begin(),Y.end(),y[i])-Y.begin()+1; point[i]=coordinate(x[i],y[i],p[i]); } sort(point+1,point+n+1); for (int i=1;i<=m;i++) { int x1=read(),y1=read(),x2=read(),y2=read(); x1=lower_bound(X.begin(),X.end(),x1)-X.begin()+1; y1=lower_bound(Y.begin(),Y.end(),y1)-Y.begin()+1; x2=upper_bound(X.begin(),X.end(),x2)-X.begin(); y2=upper_bound(Y.begin(),Y.end(),y2)-Y.begin(); q[++cnt]=node(x1-1,y1,y2,i); q[++cnt]=node(x2,y1,y2,i); } sort(q+1,q+cnt+1); int now=1; for (int i=1;i<=cnt;i++) { while (point[now].x<=q[i].x&&now<=n) add(point[now].y,point[now].p),now++; if (!ans[q[i].pos]) ans[q[i].pos]=qry(q[i].r)-qry(q[i].l-1); else ans[q[i].pos]=qry(q[i].r)-qry(q[i].l-1)-ans[q[i].pos]; } for (int i=1;i<=m;i++) printf("%lld\n",ans[i]); return 0; } (就不能开512MB的空间吗???)

转载请注明原文地址: https://www.6miu.com/read-75529.html

最新回复(0)