C-sequence
Meaning of the questions:
Title of length n is given two arrays a, b, determined
analysis:
Standard Solution:
Code:
(+ Monotone stack segment tree)
#include<iostream> #include<stack> #include<cstring> #include<queue> #include<algorithm> #include<cstdio> using namespace std; const int MAX=3e6+9; const int INF=0x3f3f3f3f; typedef long long ll; #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 int n; int l[MAX],r[MAX],a[MAX],b[MAX]; ll sum[MAX]; stack<int>st; struct tree{ //线段树维护前缀和最大最小值 ll mx,mn; }tree[MAX<<2]; void PushUp(int rt) { tree[rt].mx=max(tree[rt<<1].mx,tree[rt<<1|1].mx); tree[rt].mn=min(tree[rt<<1].mn,tree[rt<<1|1].mn); } void Build(int l,int r,int rt) { if(l==r) { tree[rt].mx=sum[l]; tree[rt].mn=sum[l]; return; } int m=l+r>>1; Build(ls);Build(rs); PushUp(rt); } ll Query_min(int L,int R,int l,int r,int rt) { ll ans=INF; if(L<=l&&r<=R) return tree[rt].mn; int m=l+r>>1; if(L<=m)ans=min(ans,Query_min(L,R,ls)); if(R>m)ans=min(ans,Query_min(L,R,rs)); return ans; } ll Query_max(int L,int R,int l,int r,int rt) { ll ans=-INF; if(L<=l&&r<=R) return tree[rt].mx; int m=l+r>>1; if(L<=m)ans=max(ans,Query_max(L,R,ls)); if(R>m)ans=max(ans,Query_max(L,R,rs)); return ans; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=n;i++)scanf("%d",&b[i]); for(int i=1;i<=n;i++)sum[i]=b[i]+sum[i-1]; Build(1,n,1); a[0]=a[n+1]=-INF; for(int i=0;i<=n+1;i++) { while(!st.empty()&&a[st.top()]>a[i]) //单调栈维护以每个a[i]为最小值的区间左右端点 { r[st.top()]=i-1; st.pop(); } if(!st.empty())l[i]=st.top()+1; st.push(i); } // for(int i=1;i<=n;i++)cout<<l[i]<<' '<<r[i]<<endl; ll ans=-INF; for(int i=1;i<=n;i++) { if(a[i]>=0) { ll h=(ll)a[i]*(sum[r[i]]-sum[l[i]-1]); if(h>ans) ans=h; } else {//a[i]为负数 取区间和最小 ll mx=Query_max(l[i],i,1,n,1); ll mn=Query_min(i,r[i],1,n,1); ll h=(ll)a[i]*(mn-mx); if(h>ans)ans=h; } } printf("%lld\n",ans); return 0; }
A-meeting
Meaning of the questions:
There is a city, there are n interesting places are numbered 1 ~ n, is now in place x1, x2 ..., xk a man they want
Find a place to meet, at least ask how much time it will take.
analysis:
Standard straightforward solution to a problem, tql
Error: I do not communicate mentally, I feel determined lca between all points, d and then take the maximum points to lca can. But just
Think simple counter-examples can be found, such as a 1-> 22-> 33-> 41-> lca 5 thus found is 1, 1, and 5 is the shortest distance aggregation
3 but in fact brought together in the shortest cost is 2 points 3
Code:
(X1 ~ xk find all points in lca from the furthest point to another point and then find the point of maximum distance, taking half rounded up)
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int MAX=1e5+9; struct Edge{ int to,val,next; }edge[MAX*2]; int head[MAX],cnt=0; int deep[MAX],dis[MAX]; int up[MAX][20]; int n,k,a,b,x[MAX]; inline void add(int u,int v,int w) { edge[cnt].val=w; edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt++; } void dfs(int u) { for(int i=head[u];i!=-1;i=edge[i].next) { int to=edge[i].to; if(up[u][0]==to)continue; deep[to]=deep[u]+1; dis[to]=dis[u]+edge[i].val; up[to][0]=u; dfs(to); } } void init() { for(int j=1;(1<<j)<=n;j++) for(int i=1;i<=n;i++) up[i][j]=up[up[i][j-1]][j-1]; } int LCA(int a,int b) { if(deep[a]<deep[b])swap(a,b); int d=deep[a]-deep[b]; for(int i=0;i<20;i++) if((1<<i)&d) a=up[a][i]; if(a==b)return a; for(int i=19;i>=0;i--) { if(up[a][i]!=up[b][i]) a=up[a][i],b=up[b][i]; } return up[a][0]; } int get_dis(int a,int b,int lca) { return dis[a]+dis[b]-dis[lca]*2; } int main() { memset(head,-1,sizeof(head)); scanf("%d%d",&n,&k); for(int i=1;i<n;i++) { scanf("%d%d",&a,&b); add(a,b,1),add(b,a,1); } dfs(1);init(); for(int i=1;i<=k;i++) scanf("%d",&x[i]); if(k==1)printf("0\n"); else { int lca=x[1]; for(int i=2;i<=k;i++) lca=LCA(x[i],lca); int mx=0,pos,ans=0; for(int i=1;i<=k;i++) //离所有点lca最远的点 { if(MX <DIS [X [I]] - DIS [LCA]) { MX = DIS [X [I]] - DIS [LCA]; POS = X [I]; } } for ( int I = . 1 ; I < K =; I ++) // find the point farthest away, and taking half the distance, rounded up { ANS = max (ANS, (get_dis (POS, X [I], the LCA (POS, X [I])) + . 1 ) / 2 ); } the printf ( " % D \ n- " , ANS); } return 0 ; }