博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ACM 竞赛高校联盟 练习赛 第六场 光头强的强迫症(线段树)
阅读量:4328 次
发布时间:2019-06-06

本文共 2686 字,大约阅读时间需要 8 分钟。

链接:https://nanti.jisuanke.com/t/16878

分析:先挖个坑。。这题貌似有问题,按题意应该是能砍则砍,但是样例是按能得到的最大数来算的。。下面先按能砍则砍来分析。。

首先预处理一下,f[i]表示从1砍到i,能砍的最大数,b[i]表示如果把i砍了,从i往后一共能砍多少棵,MAX[i]表示从1到i,砍过的树中的最大高度。f和MAX直接O(n)处理就行了,b[i]用线段树来处理,b[i]=b[j]+1,j是满足h[j]>h[i]且j>i的j中最小值,复杂度为O(nlogn)。

然后询问,如果b>MAX[a-1],第a棵修改后依然要砍,因此ans=1+f[a-1]+b[j],j是满足j>a且h[j]>b的j中最小值;否则,不砍第a棵,ans=f[a-1]+b[j],j是满足j>a且h[j]>MAX[a-1]的j中最小值。复杂度为O(nlogn)。

以下代码不能AC,样例都过不了。。坐等出题人修改题意或样例再改。。。

1 #include
2 #include
3 #include
4 using namespace std; 5 const int maxn=4e5+5; 6 int n,m; 7 class segTree{ 8 public: 9 int a[maxn],s[maxn*4];10 void build(int node,int begin,int end){11 if(begin==end){12 s[node]=begin;13 }else{14 build(2*node,begin,(begin+end)/2);15 build(2*node+1,(begin+end)/2+1,end);16 if(a[s[2*node]]>=a[s[2*node+1]])17 s[node]=s[2*node];18 else19 s[node]=s[2*node+1];20 }21 }22 int query(int node,int begin,int end,int left,int right,int low_bound){23 if(left>end||right
=left&&end<=right)26 // return s[node];27 if(begin==end){28 if(a[begin]>low_bound)return begin;29 return -1;30 }31 int q1,q2;32 if(a[s[2*node]]>low_bound)return query(2*node,begin,(begin+end)/2,left,right,low_bound);33 if(a[s[2*node+1]]>low_bound)return query(2*node+1,(begin+end)/2+1,end,left,right,low_bound);34 return -1;35 }36 }st;37 int Max[maxn],sum_front[maxn],sum_back[maxn];38 int h[maxn];39 int main(){40 // freopen("e:\\in.txt","r",stdin);41 scanf("%d%d",&n,&m);42 Max[0]=0,sum_front[0]=0;43 for(int i=1;i<=n;i++){44 scanf("%d",&h[i]);45 st.a[i]=h[i];46 if(h[i]>Max[i-1]){47 sum_front[i]=sum_front[i-1]+1;48 Max[i]=h[i];49 }else{50 sum_front[i]=sum_front[i-1];51 Max[i]=Max[i-1];52 }53 }54 int k;55 ta.init(n);56 st.build(1,1,n);57 sum_back[n]=1;58 for(int i=n-1;i>=1;i--){59 k=st.query(1,1,n,i+1,n,h[i]);60 if(k!=-1)sum_back[i]=1+sum_back[k];61 else sum_back[i]=1;62 }63 int a,b;64 for(int i=0;i
Max[a-1]){68 ans++;69 k=st.query(1,1,n,a+1,n,b);70 if(k!=-1)ans+=sum_back[k];71 }else{72 k=st.query(1,1,n,a+1,n,Max[a-1]);73 if(k!=-1)74 ans+=sum_back[k];75 }76 printf("%d\n",ans);77 }78 return 0;79 }

 

转载于:https://www.cnblogs.com/7391-KID/p/7478889.html

你可能感兴趣的文章
UIDynamic(物理仿真)
查看>>
Windows下安装Redis
查看>>
迷宫实现
查看>>
【字符编码】Java字符编码详细解答及问题探讨
查看>>
学习操作系统导图
查看>>
在线的JSON formate工具
查看>>
winform非常实用的程序退出方法!!!!!(转自博客园)
查看>>
xml解析
查看>>
centos安装vim
查看>>
linux工作调度(计划任务)
查看>>
hdu--1698 Just a Hook(线段树+区间更新+懒惰标记)
查看>>
SynchronousQueue
查看>>
Python学习笔记-EXCEL操作
查看>>
依照特定轨迹遍历字符串图
查看>>
Mantis 1.1.0 报告问题中设置必填项或取消必填项[Z]
查看>>
爬虫添加代理
查看>>
POJ 题目1204 Word Puzzles(AC自己主动机,多个方向查询)
查看>>
oracle经常使用函数(2)
查看>>
Iocomp控件之数字显示【图文】
查看>>
Androd开发之广告栏设计
查看>>