hdu 5338
来源:互联网 发布:广安门中医院挂号软件 编辑:程序博客网 时间:2024/06/16 03:41
因为起名无能,所以数组意义弄混了,一直wr,终于过了,结论就是好好学英语,养成自己起名的一贯习惯。这道题的重点在于怎么找有效区间内最大的值,通过看别的代码(http://blog.csdn.net/winddreams/article/details/47156293),才发现原来可以这样写。好多天了,终于把这道题过了,披着组合数学外衣的线段树!!!!!!
(今天中午吃的砂锅麻花,再一次感叹,学校的砂锅,即使夏天吃,也很好吃,想吃木桶豆腐和羊肉泡馍。)
2015.8.29:
对于数的大小比较和字典序的大小比较似乎都会有一个贪心的过程。
(如果有人在说,学数学有什么意义的话,我就可以正大光明的告诉它,可以在csdn的博客里写文章,每次的验证码都让我感觉回到了小学,每天30道计算题)
#include<stdio.h>#include<string.h>#include<iostream>using namespace std;#define N 100010struct node{ int maxnum; int maxb;};struct node array[4*N];int num[N];int loca[N];int ans[N];int sign[N];int a,b;int max(int a,int b){ return a>b?a:b;}void update(int root){ array[root].maxnum=max(array[root<<1].maxnum,array[(root<<1)+1].maxnum); array[root].maxb=max(array[root<<1].maxb,array[(root<<1)+1].maxb); return;}void build(int root,int l,int r){ if(l==r){ scanf("%d",&num[l]); array[root].maxnum=num[l]; array[root].maxb=0; loca[num[l]]=l; return; } else{ int middle=(l+r)>>1; build(root<<1,l,middle); build((root<<1)+1,middle+1,r); update(root); return; }}int queryb(int root,int l,int r){ //printf("%d %dha %d %dhei ",l,r,a,b); if(a>b){ return -1; } else{ if(a<=l&&b>=r){ return array[root].maxb; } else{ int middle=(l+r)>>1; if(b<=middle){ return queryb(root<<1,l,middle); } else if(a>middle){ return queryb((root<<1)+1,middle+1,r); } else{ return max(queryb(root<<1,l,middle),queryb((root<<1)+1,middle+1,r)); } } }}int querynum(int root,int l,int r){ if(l==r){ return array[root].maxnum; } else{ int middle=(l+r)>>1; if(a<=l&&b>=r){ return array[root].maxnum; } else{ if(b<=middle){ return querynum(root<<1,l,middle); } else if(a>middle){ return querynum((root<<1)+1,middle+1,r); } else{ return max(querynum(root<<1,l,middle),querynum((root<<1)+1,middle+1,r)); } } }}void updateb(int root,int l,int r){ if(l==r){ array[root].maxb=l; return; } else{ int middle=(l+r)>>1; if(a<=middle){ updateb(root<<1,l,middle); } else{ updateb((root<<1)+1,middle+1,r); } update(root); return; }}void updatenum(int root,int l,int r){ if(l==r){ array[root].maxnum=-1; return; } else{ int middle=(l+r)>>1; if(a<=middle){ updatenum(root<<1,l,middle); } else{ updatenum((root<<1)+1,middle+1,r); } update(root); return; }}int main(){ int t; int n; scanf("%d",&t); while(t--){ scanf("%d",&n); if(n==0){ continue; } memset(array,0,sizeof(array)); build(1,1,n); memset(ans,-1,sizeof(ans)); memset(sign,0,sizeof(sign)); for(int i=1;i<=n;i++){ if(ans[i]!=-1){ continue; } else{ int k1,k2,k3; a=1; b=loca[i]-1; int templ=queryb(1,1,n);//printf("wo shi da hao ren"); templ++; if(templ==0||templ==loca[i]){ k1=-1; } else{ a=templ; b=loca[i]-1; k1=querynum(1,1,n); }//k1的值已验证正确 if((loca[i]-1>=1)&&ans[num[loca[i]-1]]==i){ k2=-1; } else{ k2=i; } /*if(i==4){ printf("%d %d\n",ans[loca[i]+1],ans[5]); }*/ if((loca[i]+1<=n)&&(ans[num[loca[i]+1]]==-1)){ k3=num[loca[i]+1]; } else if((loca[i]+1<=n)&&num[loca[i]+1]<i&&ans[num[loca[i]+1]]!=num[loca[i]+1]&&sign[num[loca[i]+1]]==0){ k3=num[loca[i]+1]; } else{ k3=-1; } if(k1>k2&&k1>k3){ sign[k1]=1; for(int j=loca[k1];j<loca[i];j++){ ans[num[j]]=num[j+1]; } ans[i]=k1; a=loca[i]; updateb(1,1,n); } else if(k2>k1&&k2>k3){ sign[k2]=1; ans[i]=k2; a=loca[i]; updateb(1,1,n); } else if(k3>k1&&k3>k2){ ans[i]=k3; a=loca[k3]; updatenum(1,1,n); } //printf("%d %d %d %d\n",i,k1,k2,k3); } } printf("%d",ans[1]); for(int i=2;i<=n;i++){ printf(" %d",ans[i]); } printf("\n"); } return 0;}
0 0
- hdu 5338
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- jni demo 求和
- iOS开发 - mac下svn客户端的使用
- Web用户行为跟踪收集
- vs2008 MFC程序 读取显示图像、更改背景图像
- centos vagrant virtualbox
- hdu 5338
- mvn 请使用 -source 7 或更高版本以启用 diamond 运算符
- mysql 备份工具xtrabackup(一)
- easyui datagrid 显示横行滚动条
- (已成功)Github的使用
- poj 2406 Power Strings (KMp)
- VB.net调用C++ 6.0 DLL内部函数
- hdu 5363 Key Set (2015多校第六场第11题)找规律推公式
- linux基础——在redhat6下配置yum源的使用