LOADING

加载过慢请开启缓存,浏览器默认开启

daily 3

2023/3/17 daily

CF 722C

区间并查集,对于某个点来说,如果他左侧/右侧的点已经被加入集合中去了,那么就把该点的值加入对应的集合,我们倒着进行添加即可

vector<int>fa;
vector<ll>sum;
int find(int x){
  return fa[x]==x?x:fa[x]=find(fa[x]);
}
void merge(int x,int y){
  int fx=find(x),fy=find(y);
  if(fx==fy)return;
  sum[fx]+=sum[fy];
  fa[fy]=fx;
}
void solve(){
  int n;cin>>n;
  fa.resize(n+1);
  sum.resize(n+1);
  iota(fa.begin(),fa.end(),0);
  vector<int>ord(n+1),vis(n+2);
  for(int i=1;i<=n;++i)cin>>sum[i];
  for(int i=1;i<=n;++i)cin>>ord[i];
  vector<ll>ans(n+1);
  ll res=0;
  for(int i=n;i>=1;--i){
    ans[i]=res;
    if(vis[ord[i]-1]){
      merge(ord[i]-1,ord[i]);
    }
    if(vis[ord[i]+1]){
      merge(ord[i]+1,ord[i]);
    }
    int f=find(ord[i]);
    res=max(res,sum[find(ord[i])]);
    vis[ord[i]]=1;
  }
  for(int i=1;i<=n;++i){
    cout<<ans[i]<<"\n";
  }
  return;
}

CF 731F

后缀和好题,我们知道,对于某个落在 [ka[i],(k+1) \ a[i]的数,最终取值是k*a[i],那么我们对后缀取后缀和,然后每一段进行计算,注意不要重复计算,标记vis数组即可

void solve(){
  int n;
  cin>>n;
  vector<int>a(n+1);
  vector<ll>sum(MAXN),vis(sum);
  for(int i=1;i<=n;++i){
    cin>>a[i];
    sum[a[i]]++;
  }
  sort(a.begin()+1,a.end());
  for(int i=a[n]-1;i>=0;--i){
    sum[i]+=sum[i+1];
  }
  ll ans=0;
  for(int i=1;i<=n;++i){
    if(vis[a[i]])continue;
    ll res=0;
    int cnt=1;
    for(int j=a[i];j<=a[n];j+=a[i]){
      res+=sum[j]*a[i];
      vis[j]=1;
    }
    ans=max(ans,res);
    vis[a[i]]=1;
  }
  cout<<ans<<'\n';
  return;
}

CF 721D

不会做,看了题解发现是低能题
首先我们可以证明,对绝对值比较小的数进行操作比较好(这里就不证明了,很sb)
然后我们拿个set存数就好了

using pii=pair<ll,int>;
void solve(){
  int n,k,x;
  cin>>n>>k>>x;
  vector<ll>a(n+1);
  bool sign=false;
  set<pii>st;
  for(int i=1;i<=n;++i){
    cin>>a[i];
    if(a[i]<0){
        sign=!sign;
    }
    st.insert({abs(a[i]),i});
  }
  for(int i=1;i<=k;++i){
    auto id=st.begin()->second;
    st.erase(st.begin());
    if(a[id]<0)sign=!sign;
    if(sign){
        a[id]+=x;
    }
    else
    {
        a[id]-=x;
    }
    if(a[id]<0)sign=!sign;
    st.insert({abs(a[id]),id});
  }
  for(int i=1;i<=n;++i){
    cout<<a[i]<<" \n"[i==n];
  }
  return;
}