#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<deque> #include<set> #include<map> #include<ctime> #define LL long long #define inf 0x7ffffff #define pa pair<int,int> #define pi 3.1415926535897932384626433832795028841971 using namespace std; inline LL read() { LL x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } struct ydat{int d,rnk;}yy[100010];bool operator<(ydat a,ydat b){return a.d<b.d;} struct peo{int x,y,z;}p[100010];bool operator<(peo a,peo b){return a.x<b.x||a.x==b.x&&a.y<b.y;} struct segtree{int l,r,mx;}tree[500010]; int n,m,k,cnt,mx; int f[100010]; inline void update(int k) {tree[k].mx=max(tree[k<<1].mx,tree[k<<1|1].mx);} inline void buildtree(int now,int l,int r) { tree[now].l=l;tree[now].r=r; if (l==r)return; int mid=(l+r)>>1; buildtree(now<<1,l,mid); buildtree(now<<1|1,mid+1,r); } inline int ask(int now,int x,int y) { int l=tree[now].l,r=tree[now].r; if (l==x&&y==r)return tree[now].mx; int mid=(l+r)>>1; if (mid>=y)return ask(now<<1,x,y); else if (x>mid)return ask(now<<1|1,x,y); else return max(ask(now<<1,x,mid),ask(now<<1|1,mid+1,y)); } inline void add(int now,int x,int dat) { int l=tree[now].l,r=tree[now].r; if (l==r) { tree[now].mx=max(tree[now].mx,dat); return; } int mid=(l+r)>>1; if(x<=mid)add(now<<1,x,dat); else add(now<<1|1,x,dat); update(now); } int main() { n=read();m=read();k=read(); for(int i=1;i<=k;i++) { p[i].x=read();p[i].y=yy[i].d=read();p[i].z=read(); yy[i].rnk=i; } sort(yy+1,yy+k+1); yy[0].d=-1; for (int i=1;i<=k;i++) { if (yy[i].d!=yy[i-1].d)cnt++; p[yy[i].rnk].y=cnt; } sort(p+1,p+k+1); buildtree(1,1,cnt); for (int i=1;i<=k;i++) { f[i]=p[i].z+ask(1,1,p[i].y); add(1,p[i].y,f[i]); mx=max(mx,f[i]); } printf("%d\n",mx); }
然后是树状数组代码(344ms):
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<deque> #include<set> #include<map> #include<ctime> #define LL long long #define inf 0x7ffffff #define pa pair<int,int> #define pi 3.1415926535897932384626433832795028841971 using namespace std; inline LL read() { LL x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } struct ydat{int d,rnk;}yy[100010];bool operator<(ydat a,ydat b){return a.d<b.d;} struct peo{int x,y,z;}p[100010];bool operator<(peo a,peo b){return a.x<b.x||a.x==b.x&&a.y<b.y;} int c[100010]; int n,m,k,cnt,mx; int f[100010]; inline int lowbit(int x){return x&(-x);} inline void add(int x,int d) { for (int i=x;i<=cnt;i+=lowbit(i)) c[i]=max(c[i],d); } inline int ask(int x) { int s=0; for (int i=x;i;i-=lowbit(i)) s=max(s,c[i]); return s; } int main() { n=read();m=read();k=read(); for(int i=1;i<=k;i++) { p[i].x=read();p[i].y=yy[i].d=read();p[i].z=read(); yy[i].rnk=i; } sort(yy+1,yy+k+1); yy[0].d=-1; for (int i=1;i<=k;i++) { if (yy[i].d!=yy[i-1].d)cnt++; p[yy[i].rnk].y=cnt; } sort(p+1,p+k+1); for (int i=1;i<=k;i++) { f[i]=p[i].z+ask(p[i].y); add(p[i].y,f[i]); mx=max(mx,f[i]); } printf("%d\n",mx); }
最后我把树状数组的代码卡常数卡到了不能看的地步,居然卡到了308ms提交排名的rank1
#include<cstdio> #include<algorithm> using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } struct ydat{int d,rnk;}yy[100010]; inline bool operator<(const ydat &a,const ydat &b){return a.d<b.d;} struct peo{int x,y,z;}p[100010]; inline bool operator<(const peo &a,const peo &b){return a.x<b.x||a.x==b.x&&a.y<b.y;} inline int max(const int &a,const int &b){return a>b?a:b;} int c[100010]; int n,m,k,cnt,mx,now; inline int lowbit(int x){return x&(-x);} inline void add(int x,int d) { for (int i=x;i<=cnt;i+=lowbit(i)) c[i]=max(c[i],d); } inline int ask(int x) { int s=0; for (int i=x;i;i-=lowbit(i)) s=max(s,c[i]); return s; } int main() { n=read();m=read();k=read(); for(int i=1;i<=k;i++) { p[i].x=read();yy[i].d=read();p[i].z=read(); yy[i].rnk=i; } sort(yy+1,yy+k+1); yy[0].d=-1; for (int i=1;i<=k;i++) { if (yy[i].d!=yy[i-1].d)cnt++; p[yy[i].rnk].y=cnt; } sort(p+1,p+k+1); for (int i=1;i<=k;i++) { now=p[i].z+ask(p[i].y); add(p[i].y,now); mx=max(mx,now); } printf("%d\n",mx); }
bzoj1537 [POI2005]Aut- The Bus
原文:http://www.cnblogs.com/zhber/p/4141293.html