[Poi2010]Monotonicity 2 线段树
2017-07-27 20:32
344 查看
这道题考试的时候先打了个dfs暴力。又打了个O(n²)的动规。然后竟然心血来潮拍了一下。。明明知道过不去的。。。然后水了50分(20个测试点这么多啊啊啊啊)。
因为它已经提前给你如果长度为i时下一位的符号,显然O(n²)的打法大家都会打。
然后我们就考虑如何降低复杂度。
因为我们要求的是符合条件的前缀最大值,可以使用线段树来维护。
线段树的下标是权值,内容是最长长度。
一共三种情况:<,>,=。
我们需要单独存这三种情况。以大于为例:
线段树里面存的是某个权值下,下一位是大于号的所有最优长度。
至于等于可以用数组记录,不必用线段树。
然后我们更新的时候,对于f[i]=max{权值(0,a[i]-1)中所有后边符号是小于的最大值,权值(a[i]+1,inf)中所有后边符号是大于的最大值,相等的最大值}+1;
再根据f[i]的长度确定后边一位是什么符号,再把f[i]加入对应的线段树中。
复杂度O(n㏒n)。
因为它已经提前给你如果长度为i时下一位的符号,显然O(n²)的打法大家都会打。
for(i..1..n) for(j..1..i-1) if(符合条件) f[i]=max(f[i],f[j]+1);
然后我们就考虑如何降低复杂度。
因为我们要求的是符合条件的前缀最大值,可以使用线段树来维护。
线段树的下标是权值,内容是最长长度。
一共三种情况:<,>,=。
我们需要单独存这三种情况。以大于为例:
线段树里面存的是某个权值下,下一位是大于号的所有最优长度。
至于等于可以用数组记录,不必用线段树。
然后我们更新的时候,对于f[i]=max{权值(0,a[i]-1)中所有后边符号是小于的最大值,权值(a[i]+1,inf)中所有后边符号是大于的最大值,相等的最大值}+1;
再根据f[i]的长度确定后边一位是什么符号,再把f[i]加入对应的线段树中。
复杂度O(n㏒n)。
#include<cstdio> #include<cstring> #include<iostream> using namespace std; #define pos(i,a,b) for(int i=(a);i<=(b);i++) #define N 2020200 int a ,n,k; char s ; int cun ,f ; int ans; int ma; struct haha{ int left,right,num; }; haha treeda[N*4];haha treexiao[N*4]; void buildda(int x,int left,int right){ treeda[x].left=left; treeda[x].right=right; if(left==right){ treeda[x].num=0; return; } int mid=(left+right)>>1; buildda(x*2,left,mid); buildda(x*2+1,mid+1,right); } int queryda(int left,int right,int root){ if(treeda[root].left==left&&treeda[root].right==right){ return treeda[root].num; } int mid=(treeda[root].left+treeda[root].right)>>1; if(right<=mid){ return queryda(left,right,root*2); } else{ if(left>mid){ return queryda(left,right,root*2+1); } else{ return max(queryda(left,mid,root*2),queryda(mid+1,right,root*2+1)); } } } void changeda(int x,int num,int root){ if(treeda[root].left==treeda[root].right){ treeda[root].num=num; return; } treeda[root].num=max(treeda[root].num,num); if(x<=treeda[root*2].right) changeda(x,num,root*2); else changeda(x,num,root*2+1); } void buildxiao(int x,int left,int right){ treexiao[x].left=left; treexiao[x].right=right; if(left==right){ treexiao[x].num=0; return; } int mid=(left+right)>>1; buildxiao(x*2,left,mid); buildxiao(x*2+1,mid+1,right); } int queryxiao(int left,int right,int root){ if(treexiao[root].left==left&&treexiao[root].right==right){ return treexiao[root].num; } int mid=(treexiao[root].left+treexiao[root].right)>>1; if(right<=mid){ return queryxiao(left,right,root*2); } else{ if(left>mid){ return queryxiao(left,right,root*2+1); } else{ return max(queryxiao(left,mid,root*2),queryxiao(mid+1,right,root*2+1)); } } } void changexiao(int x,int num,int root){ if(treexiao[root].left==treexiao[root].right){ treexiao[root].num=num; return; } treexiao[root].num=max(treexiao[root].num,num); if(x<=treexiao[root*2].right) changexiao(x,num,root*2); else changexiao(x,num,root*2+1); } int deng ; int Max(int a,int b,int c){ return max(max(a,b),c); } int main(){ //freopen("mot.in","r",stdin); //freopen("mot.out","w",stdout); scanf("%d%d",&n,&k); pos(i,1,n){ scanf("%d",&a[i]); ma=max(ma,a[i]); } pos(i,1,k){ scanf("%s",&s[i]); } pos(i,1,n-1){ cun[i]=s[(i-1)%k+1]; } buildxiao(1,0,ma); buildda(1,0,ma); pos(i,1,n){ int tmp1,tmp2; if(a[i]==ma){ tmp1=1; } else{ tmp1=queryda(a[i]+1,ma,1); } if(a[i]==0){ tmp2=1; } else{ tmp2=queryxiao(0,a[i]-1,1); } f[i]=Max(tmp1,tmp2,deng[a[i]])+1; if(cun[f[i]]=='>'){ changeda(a[i],f[i],1); } if(cun[f[i]]=='<'){ changexiao(a[i],f[i],1); } if(cun[f[i]]=='='){ deng[a[i]]=max(deng[a[i]],f[i]); } ans=max(ans,f[i]); } printf("%d",ans); return 0; }
相关文章推荐
- 线段树优化DP [Poi2010]Monotonicity 2
- 【BZOJ2090/2089】[Poi2010]Monotonicity 2 动态规划+线段树
- [Poi2010]Monotonicity 2
- bzoj 2090 [Poi2010]Monotonicity 2 树状数组 dp 贪心
- BZOJ2090: [Poi2010]Monotonicity 2
- [Poi2010]Monotonicity 2
- BZOJ 2090 [Poi2010]Monotonicity 2 DP+线段树
- [BZOJ2090/2089] [Poi2010]Monotonicity 2/Monotonicity 树状数组优化dp
- bzoj 2090: [Poi2010]Monotonicity 2 动态规划+线段树
- BZOJ2090 POI2010 Monotonicity
- BZOJ2090/2089 [Poi2010]Monotonicity 2/Monotonicity
- BZOJ2089&2090: [Poi2010]Monotonicity 2
- BZOJ2090 : [Poi2010]Monotonicity 2
- bzoj2089&2090: [Poi2010]Monotonicity
- BZOJ 3747 POI 2015 Kinoman 线段树
- BZOJ 2084 [Poi2010]Antisymmetry Manacher
- [BZOJ 2087] POI 2010 Sheep
- [动态MST] [CDQ分治] BZOJ2001: [Hnoi2010]City 城市建设
- BZOJ2091: [Poi2010]The Minima Game
- BZOJ 2085 [Poi2010]Hamsters Hash+倍增floyd