【fhqtreap】航空管制

来源:互联网 发布:西安软件公寓软件新城 编辑:程序博客网 时间:2024/06/09 15:10

飞机因为航空管制晚点了一个多小时,于是正好学习一下fhq介绍过的treap...

poj2352

#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;int l[200000],r[200000],s[2000000],w[200000],x[200000],y[200000];int ss,root,n,ans[200000];bool random(double p){return (double)rand()/RAND_MAX<p;}void print(int x){if (!x) return ;cout<<x<<' '<<l[x]<<' '<<r[x]<<endl;print(l[x]),print(r[x]);}int ori(int x){++ss,l[ss]=r[ss]=0;w[ss]=x,s[ss]=1;return ss;}void updata(int x){s[x]=s[l[x]]+1+s[r[x]];}int merge(int x,int y){if (!x) return y;if (!y) return x;if (random((double)s[x]/(s[x]+s[y]))) {r[x]=merge(r[x],y),updata(x);return x;}l[y]=merge(x,l[y]),updata(y);return y;}void split(int root,int k,int &a,int &b){if (!root) {a=b=0;return ;}if (w[root]>k) { int p,q;split(l[root],k,p,q);l[root]=0,updata(root);a=p,b=merge(q,root);return ;}int p,q;//保证根节点被选 split(r[root],k,p,q);r[root]=0,updata(root);a=merge(root,p),b=q;return ;}int ask(int x){int a,b;split(root,x,a,b);int ans=s[a];root=merge(a,b);return ans;}int main(){freopen("input.txt","r",stdin);scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);root=ss=0;for (int i=1;i<=n;i++) {int sum=ask(x[i]);ans[sum]++;int a,b;split(root,x[i],a,b);root=ori(x[i]);root=merge(a,root),root=merge(root,b);}for (int i=0;i<n;i++) printf("%d\n",ans[i]);return 0;}

poj3580

上飞机前没调出来...

用叉姐的rand函数tle了,原因是值域只有32767,但是即便扩大范围也用了1900+ms,而黄哥的程序不但各种指针,stl,rand函数值域也只有32767还比我要快,难道真的是数组寻址太慢了不成...不过数据范围应该没那么大

值得一提的是我以前同样是数组实现的splay也比这个treap快的多,虽然说用这个treap处理某些操作非常方便...

#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#include <ctime>const int oo=1073741819;const int Rand_Max=2147483647;using namespace std;int l[250000],r[250000],w[250000],s[250000],Min[250000];int Ad[250000],Sw[250000];int root,ss,n,m;void print(int x){if (!x) return ;cout<<x<<' '<<l[x]<<' '<<r[x]<<endl;print(l[x]);print(r[x]);}inline int ran(){static int x = 1;x += (x << 2) + 1;return x & 2147483647;}bool random(double p){return (double) (ran())/Rand_Max < p;}int ori(int x){++ss,l[ss]=r[ss]=0;w[ss]=x,s[ss]=1,Min[ss]=x;Ad[ss]=0,Sw[ss]=0;return ss;}void add(int x,int W){if (!x) return ;w[x]+=W,Ad[x]+=W,Min[x]+=W;}void swap(int x){if (!x) return ;int e;e=l[x],l[x]=r[x],r[x]=e;Sw[x]^=1;}void updata(int x){if (!x) return ;s[x]=s[l[x]]+s[r[x]]+1;Min[x]=min(Min[l[x]],min(Min[r[x]],w[x]));}void pushdown(int x){if (!x) return ;if (Ad[x]) {add(l[x],Ad[x]),add(r[x],Ad[x]);Ad[x]=0;}if (Sw[x]) {swap(l[x]),swap(r[x]);Sw[x]=0;}updata(x);}int merge(int x,int y){if (!x) return y;if (!y) return x;//if (random((double)s[x]/(s[x]+s[y]))) {//if (w[x]<w[y]) {if (ran()%(s[x]+s[y])<s[x]) {pushdown(x);r[x]=merge(r[x],y);updata(x);return x;}pushdown(y);l[y]=merge(x,l[y]);updata(y);return y;}void split(int x,int k,int &a,int &b){if (!x) {a=b=0;return ;}pushdown(x);if (s[l[x]]>=k) {int p,q;split(l[x],k,p,q);l[x]=0,updata(x);a=p,b=merge(q,x);return ;}int p,q;split(r[x],k-(s[l[x]]+1),p,q);r[x]=0,updata(x);a=merge(x,p),b=q;return ;}int main(){freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);scanf("%d",&n);root=ss=0,Min[0]=oo,s[0]=0,w[0]=oo;for (int i=1;i<=n;i++) {int x;scanf("%d",&x);int y=ori(x);root=merge(root,y);}scanf("%d",&m);char ch[200];//print(root);for (int i=1;i<=m;i++) {scanf("%s",ch+1);if ('A'==ch[1]) {int x,y,z;scanf("%d%d%d",&x,&y,&z);int a,b,c,d;split(root,x-1,a,b);split(b,y-x+1,c,d);add(c,z);root=merge(a,merge(c,d));}else if ('R'==ch[1] && 'E'==ch[4]) {int x,y;scanf("%d%d",&x,&y);int a,b,c,d;split(root,x-1,a,b);split(b,y-x+1,c,d);swap(c);root=merge(a,merge(c,d));}else if ('R'==ch[1] && 'O'==ch[4]) {int x,y,z;scanf("%d%d%d",&x,&y,&z);//if ((z>(y-x+1))) continue;z%=(y-x+1);int a,b,c,d,e,f;split(root,x-1,a,b);split(b,y-x+1,c,d);split(c,(y-x+1)-z,e,f);root=merge(a,merge(f,merge(e,d)));}else if ('I'==ch[1]) {int x,y;scanf("%d%d",&x,&y);int p=ori(y);int a,b;split(root,x,a,b);root=merge(a,merge(p,b));}else if ('D'==ch[1]) {int x;scanf("%d",&x);int a,b,c,d;split(root,x-1,a,b);split(b,1,c,d);root=merge(a,d);}else if ('M'==ch[1]) {int x,y;scanf("%d%d",&x,&y);int a,b,c,d;split(root,x-1,a,b);split(b,y-x+1,c,d);int ans=Min[c];root=merge(a,merge(c,d));printf("%d\n",ans);}}cout<<clock()<<endl;return 0;} 


update 2014.4.14

去掉了一个无用的updata,时间减少了100ms,又去掉了split的两个merge,时间瞬间减少了400+ms

果然细节对常数的影响巨大,不过split的两个merge确实是没有必要的,但是叉姐的板子里面有...

update 2014.5.11 

其实我也不知道去掉split的merge会不会导致树高不是log= =

#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#include <ctime>const int oo=1073741819;const int Rand_Max=1073741819;using namespace std;int l[250000],r[250000],w[250000],s[250000],Min[250000];int Ad[250000],Sw[250000];int root,ss,n,m;void print(int x){if (!x) return ;cout<<x<<' '<<l[x]<<' '<<r[x]<<endl;print(l[x]);print(r[x]);}inline int ran(){static int x = 1;x += (x << 2) + 1;return x & 1073741819;}bool random(double p){return (double) (ran())/Rand_Max < p;}int ori(int x){++ss,l[ss]=r[ss]=0;w[ss]=x,s[ss]=1,Min[ss]=x;Ad[ss]=0,Sw[ss]=0;return ss;}void add(int x,int W){if (!x) return ;w[x]+=W,Ad[x]+=W,Min[x]+=W;}void swap(int x){if (!x) return ;int e;e=l[x],l[x]=r[x],r[x]=e;Sw[x]^=1;}void updata(int x){if (!x) return ;s[x]=s[l[x]]+s[r[x]]+1;Min[x]=min(Min[l[x]],min(Min[r[x]],w[x]));}void pushdown(int x){if (!x) return ;if (Ad[x]) {add(l[x],Ad[x]),add(r[x],Ad[x]);Ad[x]=0;}if (Sw[x]) {swap(l[x]),swap(r[x]);Sw[x]=0;}//updata(x);}int merge(int x,int y){if (!x) return y;if (!y) return x;//if (random((double)s[x]/(s[x]+s[y]))) {//if (w[x]<w[y]) {if (ran()%(s[x]+s[y])<s[x]) {pushdown(x);r[x]=merge(r[x],y);updata(x);return x;}pushdown(y);l[y]=merge(x,l[y]);updata(y);return y;}void split(int x,int k,int &a,int &b){if (!x) {a=b=0;return ;}pushdown(x);if (s[l[x]]>=k) {int p,q;split(l[x],k,p,q);l[x]=q,updata(x);a=p,b=x;return ;}int p,q;split(r[x],k-(s[l[x]]+1),p,q);r[x]=p,updata(x);a=x,b=q;return ;}int main(){freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);scanf("%d",&n);root=ss=0,Min[0]=oo,s[0]=0,w[0]=oo;for (int i=1;i<=n;i++) {int x;scanf("%d",&x);int y=ori(x);root=merge(root,y);}scanf("%d",&m);char ch[200];//print(root);for (int i=1;i<=m;i++) {scanf("%s",ch+1);if ('A'==ch[1]) {int x,y,z;scanf("%d%d%d",&x,&y,&z);int a,b,c,d;split(root,x-1,a,b);split(b,y-x+1,c,d);add(c,z);root=merge(a,merge(c,d));}else if ('R'==ch[1] && 'E'==ch[4]) {int x,y;scanf("%d%d",&x,&y);int a,b,c,d;split(root,x-1,a,b);split(b,y-x+1,c,d);swap(c);root=merge(a,merge(c,d));}else if ('R'==ch[1] && 'O'==ch[4]) {int x,y,z;scanf("%d%d%d",&x,&y,&z);//if ((z>(y-x+1))) continue;z%=(y-x+1);int a,b,c,d,e,f;split(root,x-1,a,b);split(b,y-x+1,c,d);split(c,(y-x+1)-z,e,f);root=merge(a,merge(f,merge(e,d)));}else if ('I'==ch[1]) {int x,y;scanf("%d%d",&x,&y);int p=ori(y);int a,b;split(root,x,a,b);root=merge(a,merge(p,b));}else if ('D'==ch[1]) {int x;scanf("%d",&x);int a,b,c,d;split(root,x-1,a,b);split(b,1,c,d);root=merge(a,d);}else if ('M'==ch[1]) {int x,y;scanf("%d%d",&x,&y);int a,b,c,d;split(root,x-1,a,b);split(b,y-x+1,c,d);int ans=Min[c];root=merge(a,merge(c,d));printf("%d\n",ans);}}//cout<<clock()<<endl;return 0;} 


0 0
原创粉丝点击