OI 笑传 #20

我讨厌性质跟输入格式有关的东西。

20th


ARC208B

这题实现了三个版本,虽然说前两个是错的但是都是一遍写对,当练习玛丽了。

code

Show me the code
#define rd read()
#define mkp make_pair
#define ls p<<1
#define rs p<<1|1
#define rep(i,a,b) for( int i=(a); i<=(b); ++i)
#define per(i,a,b) for( int i=(a); i>=(b); --i)
#include<bits/stdc++.h>
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef __int128 i128;
i64 read(){
  i64 x=0,f=1;
  char c=getchar();
  while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
  while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
  return x*f;
}
void init(){return ;}
i64 da[1000];
i64 d[1000];
bool check(int n,i64 k,int mid){
  i64 res=0,lst=mid;
  for(int i=2;i<=n;i++){
    i64 nc=lst*2-1;
    res+=nc%lst;
    if(res>=k)break;
    lst=nc;
  }
  if(res<k)return 0;
  else return 1;
}
void solve(){
  int n,k; cin>>n>>k;
  i64 l=1,r=1e9;
  while(l<r){
    i64 mid=l+r>>1;
    if(check(n,k,mid)){
      r=mid;
    }
    else l=mid+1;
  }
  vector<i64> al;
  i64 res=0,lst=r;
  al.push_back(r);
  for(int i=2;i<=n;i++){
    i64 nc=lst*2-1;
    i64 bres=res;
    res+=nc%lst;
    if(res>=k){
      al.push_back(lst+k-bres);
      break;
    }
    else al.push_back(nc);
    lst=nc;
  }
  for(int i=1;i<=n-al.size();i++){
    cout<<1<<' ';
  }
  for(int v:al){cout<<v<<' ';}
  cout<<'\n';

  return ;
}
int main(){
  
  da[1]=1;
  da[2]=2;
  d[1]=d[2]=0;
  for(int i=3;i<=40;i++){
    da[i]=da[i-1]*2-1;
    d[i]=da[i]%da[i-1];
    d[i]=d[i-1]+d[i];
  }
  int T;cin>>T;
  while(T--){
    init();solve();
  }
  
  return 0;
}

CF1776F

轻量构造题。

code

Show me the code
#define rd read()
#define mkp make_pair
#define ls p<<1
#define rs p<<1|1
#define rep(i,a,b) for( int i=(a); i<=(b); ++i)
#define per(i,a,b) for( int i=(a); i>=(b); --i)
#include<bits/stdc++.h>
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef __int128 i128;
i64 read(){
  i64 x=0,f=1;
  char c=getchar();
  while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
  while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
  return x*f;
}
int ind[100];
struct ek{
  int u;int v;
}e[10000];
int ans[10000];
void init(){memset(ind,0,sizeof ind);return ;}
void solve(){
  int n,m;cin>>n>>m;
  for(int i=1;i<=m;i++){
    cin>>e[i].u>>e[i].v;
    ind[e[i].u]++;
    ind[e[i].v]++;
  }
  if(m==(n-1)*n/2){
    cout<<3<<'\n';
    for(int i=1;i<=m;i++){
      if(e[i].u!=1&&e[i].v!=1)ans[i]=1;
    }
    for(int i=1;i<=m;i++){
      if(e[i].u>e[i].v)swap(e[i].u,e[i].v);
      if(e[i].u==1&&e[i].v!=n)ans[i]=2;
      if(e[i].u==1&&e[i].v==n)ans[i]=3;
    }
    for(int i=1;i<=m;i++){cout<<ans[i]<<' ';}
    cout<<'\n';
    return ;
  }
  else{
    int tg=0;
    for(int i=1;i<=n;i++){
      if(ind[i]!=n-1){tg=i;break;}
    }
    for(int i=1;i<=m;i++){
      if(e[i].u!=tg&&e[i].v!=tg)ans[i]=1;
      else ans[i]=2;
    }
    cout<<2<<'\n';
    for(int i=1;i<=m;i++){cout<<ans[i]<<' ';}
    cout<<'\n';
  }
}
int main(){
  
  int T;cin>>T;
  while(T--){
    init();solve();
  }
  
  return 0;
}

CF1594D

有向边和无向边是等价的。

也打了一版错的代码,当复习 tarjan 三件套了。

code

Show me the code

ABC428C

对删除操作的处理。

code

Show me the code
#define rd read()
#define mkp make_pair
#define ls p<<1
#define rs p<<1|1
#define rep(i,a,b) for( int i=(a); i<=(b); ++i)
#define per(i,a,b) for( int i=(a); i>=(b); --i)
#include<bits/stdc++.h>
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef __int128 i128;
i64 read(){
  i64 x=0,f=1;
  char c=getchar();
  while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
  while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
  return x*f;
}
struct op{
  int l;int r;
}o[900000];
int cnt=0;
int main(){
  
  int q;cin>>q;
  int l=0,r=0;
  string s="";
  for(int i=1;i<=q;i++){
    int op;cin>>op;
    if(op==1){
      char p;cin>>p;
      s.push_back(p);
      if(p==')'){
        if(l==0)r++;
        else l--;
      }
      if(p=='('){
        l++;
      }
      cnt++;
      o[cnt].l=l;o[cnt].r=r;
    }
    if(op==2){
      s.pop_back();
      cnt--;
      l=o[cnt].l;r=o[cnt].r;
    }
    // cout<<l<<' '<<r<<'\n';
    if(r==l&&r==0)cout<<"Yes"<<'\n';
    else cout<<"No"<<'\n';
  }
  
  return 0;
}

ABC428D

完全平方数有类似倍数一样的前缀和性质,由此可以直接在得到值的范围后直接求出里面的完全平方数数量。

对值的范围的构造技巧。

code

Show me the code

ABC428E

树的直径的性质。

code

Show me the code
#define rd read()
#define mkp make_pair
#define ls p<<1
#define rs p<<1|1
#define rep(i,a,b) for( int i=(a); i<=(b); ++i)
#define per(i,a,b) for( int i=(a); i>=(b); --i)
#include<bits/stdc++.h>
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef __int128 i128;
i64 read(){
  i64 x=0,f=1;
  char c=getchar();
  while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
  while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
  return x*f;
}
const int N=5e5+5;
const int lgr=24;
vector<int> e[N];
int d[N];
void dfs1(int u,int fa){
  for(int v:e[u]){
    if(v==fa)continue;
    d[v]=d[u]+1;
    dfs1(v,u);
  }
  return ;
}
int fa[N][30];
int dep[N];
void bfs(int s){
  memset(dep,0x3f,sizeof dep);
  queue<int> q;
  q.push(s);
  dep[s]=1;dep[0]=0;
  fa[0][0]=0;fa[s][0]=0;
  while(q.size()){
    int u=q.front();
    q.pop();
    for(int v:e[u]){
      if(dep[v]>dep[u]+1){
        dep[v]=dep[u]+1;
        fa[v][0]=u;
        q.push(v);
        for(int j=1;j<=lgr;j++){
          fa[v][j]=fa[fa[v][j-1]][j-1];
        }
      }
    }
  }
  return ;
}
int lca(int a,int b){
  if(a==b)return a;
  if(dep[a]<dep[b])swap(a,b);
  for(int i=lgr;i>=0;i--)if(dep[fa[a][i]]>=dep[b])a=fa[a][i];
  if(a==b) return a;
  for(int i=lgr;i>=0;i--)if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
  return fa[a][0];
}
int main(){
  
  int n;cin>>n;
  for(int i=1;i<n;i++){
    int u,v;cin>>u>>v;
    e[u].push_back(v);
    e[v].push_back(u);
  }
  dfs1(1,0);
  int l1=0,l2=0;
  int md=0,ma=0;
  for(int i=1;i<=n;i++){
    if(md<d[i]){md=d[i];ma=i;}
    if(md==d[i]){ma=max(ma,i);}
  }
  memset(d,0,sizeof d);
  dfs1(ma,0);
  l1=ma;ma=0;md=0;
  for(int i=1;i<=n;i++){
    if(md<d[i]){md=d[i];ma=i;}
    if(md==d[i]){ma=max(ma,i);}
  }
  l2=ma;
  bfs(1);
  for(int i=1;i<=n;i++){
    int lca1=lca(i,l1);
    int lca2=lca(i,l2);
    int d1=dep[i]+dep[l1]-2*dep[lca1];
    int d2=dep[i]+dep[l2]-2*dep[lca2];
    if(d1>d2)cout<<l1<<'\n';
    else if(d1<d2)cout<<l2<<'\n';
    else cout<<max(l1,l2)<<'\n';
  }
  
  return 0;
}

ABC428F

神人线段树题。

场上想到了分成块处理 \(1 2\) 操作也知道这种东西可以用势能分析出来是均摊就行的。但是就是不会操作 \(3\)

赛后才知道由于初始 \(W_1<W_2<\cdots W_n\) 这种东西,包含位置是有单调性的。

。。。只能说还是注意力不够。

code

Show me the code

posted @ 2025-10-18 23:45  hm2ns  阅读(19)  评论(0)    收藏  举报