2017 8 13 得分:160
联考最后一天……因为不会对拍日常爆炸……
A、最长上升子串
题意:给出一个序列,允许修改一次元素,求出这个序列最长子串。
这个玩意我刚开始以为是个线性$DP$,然后……细节巨多,写出来之后出一个数据卡一个……
慌得我直喝水直上厕所……然后转到第$8$趟的时候,由于厕所比我在的那个窝风角落凉快,我的脑子算是冷静了下来,仔细一想,卧槽这不是$DP$!我可以先正序求出以每个元素开头子串长度,再倒序求出每个元素结尾子串长度,之后枚举修改位置,检查修改效果!$mdzz$……原来又是个思博题……
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 const int maxn=300005; 7 int a[maxn],f[maxn],n,g[maxn]; 8 int haha() 9 { 10 scanf("%d",&n); 11 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 12 int ans=0;a[n+1]=2147483647; 13 for(int i=n;i>=1;i--) 14 { 15 if(a[i]<a[i+1])f[i]=f[i+1]+1; 16 else f[i]=1; 17 ans=max(ans,f[i]); 18 } 19 for(int i=1;i<=n;i++) 20 { 21 if(a[i]>a[i-1])g[i]=g[i-1]+1; 22 else g[i]=1; 23 ans=max(ans,g[i]); 24 } 25 for(int i=1;i<=n;i++) 26 { 27 ans=max(f[i+1]+1,ans); 28 ans=max(g[i-1]+1,ans); 29 if(a[i-1]+1<a[i+1])ans=max(ans,f[i+1]+g[i-1]+1); 30 } 31 printf("%d ",ans); 32 } 33 int sb=haha(); 34 int main(){;}
B、中值滤波
题意:$0-1$序列左右端点不变,中间各个元素大小是以该元素为中心的长度为$3$序列的中位数。求出几次之后这个序列不再变化。
当时其实看出了些东西……当时我就意识到,连续的两个或以上相同数字连在一起这一小段就不会再发生变化,而间隔的$0$和$1$经过最多$区间长度/2$次操作也就会稳定……
然而题面中的那个$-1$把我禁锢住了……我一直在找有没有稳定不下来的情况……找不出来但总觉得有坑……于是就没有打正解……
结果那个$-1$自己就是坑……压根不存在这种情况……吔屎啦(╯‵□′)╯︵┻━┻……出题人今晚和非凡哥一起吃……
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=500005; 7 int a[maxn],n,tot[maxn],lastpos[maxn],b[maxn]; 8 int haha() 9 { 10 scanf("%d",&n); 11 for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=1; 12 int l=1,r=1,length,pos=1,ans=0; 13 while(pos<n) 14 { 15 while(a[pos]==a[pos+1]&&pos<n)b[pos]=a[pos],pos++; 16 l=pos; 17 while(a[pos]!=a[pos+1]&&pos<n)pos++;r=pos; 18 length=r-l+1; 19 if(length&1) 20 for(int i=l;i<=r;i++)b[i]=a[l]; 21 else for(int i=0;i<length>>1;i++)b[i+l]=a[l],b[r-i]=a[r]; 22 ans=max(ans,(length-1)>>1); 23 } 24 printf("%d ",ans); 25 for(int i=1;i<=n;i++)printf("%d ",b[i]); 26 } 27 int sb=haha(); 28 int main(){;}
C、约会
题意:找出树中与两点距离相等点的个数。
当时我考虑对了两种情况……
第一种:
距离是奇数,没有这样的点……
第二种:
俩玩意离$LCA$距离相等,除了这两棵子树点都可以……
然而我错了两种情况……
第一种:
俩家伙距离$LCA$不相等……个数就得是中点子树大小减去$X$在的那棵子树大小……
第二种:
一张图说明一切……
就这样还给我十分……谢天谢地……
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 const int maxn=300005; 7 struct node 8 { 9 int from,to,next; 10 }edge[maxn<<1]; 11 int head[maxn],tot; 12 void addedge(int u,int v) 13 { 14 edge[++tot]=(node){u,v,head[u]};head[u]=tot; 15 } 16 int pa[maxn],dep[maxn],siz[maxn],n; 17 void dfs(int root,int p,int deep) 18 { 19 pa[root]=p;siz[root]=1;dep[root]=deep; 20 for(int i=head[root];i;i=edge[i].next) 21 { 22 int v=edge[i].to; 23 if(pa[root]!=v) 24 { 25 pa[v]=root; 26 dfs(v,root,deep+1); 27 siz[root]+=siz[v]; 28 } 29 } 30 } 31 int rt[maxn][32]; 32 void init() 33 { 34 for(int i=1;(1<<i)<=n;i++) 35 for(int j=1;j<=n;j++)rt[j][i]=-1; 36 for(int i=1;i<=n;i++)rt[i][0]=pa[i]; 37 for(int i=1;(1<<i)<=n;i++) 38 for(int j=1;j<=n;j++) 39 if(rt[j][i-1]!=-1)rt[j][i]=rt[rt[j][i-1]][i-1]; 40 } 41 int lca(int x,int y) 42 { 43 int i;if(dep[x]<dep[y])swap(x,y); 44 for(i=0;(1<<i)<=dep[x];i++);i--; 45 for(int j=i;j>=0;j--) 46 if(dep[x]-(1<<i)>=dep[y])x=rt[x][j]; 47 if(x==y)return x; 48 for(int j=i;j>=0;j--) 49 if(rt[x][j]!=-1&&rt[x][j]!=rt[y][j])x=rt[x][j],y=rt[y][j]; 50 return pa[x]; 51 } 52 int ord[maxn]; 53 int haha() 54 { 55 scanf("%d",&n); 56 for(int i=1;i<n;i++) 57 { 58 int x,y;scanf("%d%d",&x,&y); 59 addedge(x,y);addedge(y,x); 60 } 61 dfs(1,0,1);init(); 62 for(int i=1;i<=n;i++)scanf("%d",&ord[i]); 63 } 64 int sb=haha(); 65 int main(){;}