Codeforces Round 1083 (Div. 2)vp补题

B 数学 分解质因数

k n m o d    n = 0 k^n\mod n=0 knmodn=0,k只要包含n的所有质因数就好

若 n = p 1 t 1 , k n = p 1 n , 必有 n ≥ t 1 = log ⁡ p 1 n n=p_1^{t_1},k^n=p_1^n,必有n\geq t_1=\log_{p_1}n n=p1t1,kn=p1n,必有n≥t1=logp1n

cpp 复制代码
void solve(){ 
  int n;cin>>n;
  int tp=n;
  map<int,int>m;
  forr(i,2,sqrt(n)){
    int fg=0;
    while(tp%i==0){
      fg=1;
      tp/=i;
      m[i]++;
    }
  }
  m[tp]++;
  int ans=1;
  for(auto [p,x]:m){
    ans*=p;
  }
  cout<<ans<<endl;
}

C 贪心 排序 STL


参考@_olone的题解

题意:给一系列数组,每个数组逆序后从前到后拼接数组,每种数只输出最前面的一个,让输出字典序最小

直接考虑逆序数组,最先想到的就是每次把数组字典序小的放前面

直接排序,如果像121999122345,应该122345放前面,但是排序后121999在前面,小的数会把大的数拉到前面去

所以每次选最优数组,不同数组比较应该剔除前面出现过的数(已经输出的数),同一个数组相邻重复的数作用相当于合为一个数

cpp 复制代码
void solve(){ 
  int n;cin>>n;
  vector<vint>a(n+1);
  forr(i,1,n){
    int l;cin>>l;
    int prex=-1;
    forr(j,1,l){
      int x;cin>>x;
      if(x==prex)continue;//相邻重复 不会有贡献
      prex=x;
      a[i].push_back(x);
    }
    reverse(a[i].begin(),a[i].end());// 数组越后面的 在ans里越靠前
  }
  vector<int>ans;
  map<int,int>vis;
  priority_queue<vint,vector<vint>,greater<vint>>q;
  forr(i,1,n)q.push(a[i]);
  while (q.size())
  {
    vint qv=q.top();q.pop();
    for(auto x:qv){
      if(!vis[x])ans.push_back(x),vis[x]=1;
    }
    priority_queue<vint,vector<vint>,greater<vint>>tp_q;//在每个数组里剔除小的/已经放入ans的数
    while (q.size())
    {
      qv=q.top();q.pop();
      vint newv;
      for(auto x:qv)if(!vis[x])newv.push_back(x);
      tp_q.push(newv);
      
    }
    q=tp_q;//priority_queue可以直接赋值
  }
  for(auto x:ans)cout<<x<<' ';cout<<endl;
/*以下是一开始的wa代码 没有剔除已经放过了数 会影响之后的选择

sort(a.begin()+1,a.end());
  // forr(i,1,n){for(auto x:a[i])cout<<x<<' ';cout<<endl;}
  vector<int>fg(n+1,0);

  map<int,int>pos,jud;
  
  forr(i,1,n){
    int l=a[i].size();
    forr(j,0,l-1)
    if(!pos.count(a[i][j])||jud[a[i][j]]>j){
      pos[a[i][j]]=i;
      jud[a[i][j]]=j;
    }
  }

  for(auto [num,p]:pos){
    // cout<<num<<' '<<p<<endl;
    if(fg[p])continue;
    for(auto x:a[p]){
      ans.push_back(x);
      fg[p]=1;
    }
  }
  forr(i,1,n){
    if(fg[i])continue;
    for(auto x:a[i]){
      ans.push_back(x);
    }
  }
  
  set<int>vis;
  // cout<<"ans";
  for(auto x:ans){
    if(!vis.count(x)){
      vis.insert(x);
      cout<<x<<' ';
    }
    // cout<<x<<' ';
  }
  cout<<endl;
*/
}

D 分治

题意:一个排列数组每个连续三元组,中间的数不是三元组的最大值,这个数组是酷的。每次可以选择不满足条件的三元组删去两端任一数。

由题意可知,酷数组每个连续三元组最大值位于两端。

让一个数组变酷,至少要把最大值mx一边的数全删去,mx位于边上(mx一定可以进行这样的操作)

剩下另一边的数成为一个新的数组,性质相同,可以做和原数组相同的处理,最小到三元组

cpp 复制代码
void solve(){ 
  int n;cin>>n;
  vector<int>a(n+1),pos(n+1);

  forr(i,1,n){
    cin>>a[i];
    pos[a[i]]=i;
  }
  //st表找区间最大值
  vector<vint>st(n+1,vector<int>((int)log2(n)+1));
  forr(i,1,n)st[i][0]=a[i];
  for(int j=1;(1<<j)<=n;j++){
    for(int i=1;i+(1<<j)-1<=n;i++){
      st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
    }
  }
  auto findmx=[&](int l,int r)->int{
    int len=log2(r-l+1);
    int mx=max(st[l][len],st[r-(1<<len)+1][len]);
    return pos[mx];
  };
  auto div=[&](auto&&div,int l,int r)->int{
    if(r-l+1<3)return 0;
    
    int x= findmx(l,r);
    return min(r-x+div(div,l,x-1),x-l+div(div,x+1,r));// 把最大值单边删去
  };
  cout<<div(div,1,n)<<endl;
/* 一开始想用LIS
vector<int>dp;
  dp.push_back(a[1]);
  forr(i,2,n){
    if(a[i]==mx)break;
    if(dp.back()<a[i]){
      dp.push_back(a[i]);
    }else{
      int pos=upper_bound(dp.begin(),dp.end(),a[i])-dp.begin();
      dp[pos]=a[i];
    }
  }
  int ans1=dp.size();
  forr(i,1,n){
    if(dp[0]==a[i])break;
    if(dp[0]<a[i]){
      ans1++;
      break;
    }
  }

  dp.clear();
  dp.push_back(a[1]);
  forr(i,2,n){
    if(dp.back()>a[i]){
      dp.push_back(a[i]);
    }else{
      int pos=upper_bound(dp.begin(),dp.end(),a[i],greater<int>())-dp.begin();
      dp[pos]=a[i];
    }
  }
  int ans2=dp.size();
  reforr(i,1,n){
    if(dp[ans2-1]==a[i])break;
    if(dp[ans2-1]<a[i]){
      ans2++;
      break;
    }
  }cout<<"ans";
  cout<<n-max(ans1,ans2)<<endl;
  
*/
  
}

还有一种笛卡尔树的做法 有空再学

相关推荐
happymaker06262 小时前
web前端学习日记——DAY03(盒子模型,flex布局,表格)
前端·学习
徐子元竟然被占了!!2 小时前
ENSP学习-路由器
网络·学习
cpp_25012 小时前
P1203 [IOI 1993 / USACO1.1] 坏掉的项链 Broken Necklace
数据结构·c++·算法·线性dp
_小草鱼_2 小时前
【搜索与图论】BFS(广度优先搜索)
算法·图论·bfs·宽度优先
·中年程序渣·2 小时前
Spring AI Alibaba入门学习(七)
学习
weixin_421922692 小时前
分布式日志系统实现
开发语言·c++·算法
不想看见4042 小时前
Daily Temperatures单调栈--力扣101算法题解笔记
算法
炽烈小老头2 小时前
【每天学习一点算法 2026/03/21】颜色分类
学习·算法
qyzm2 小时前
天梯赛练习题
数据结构·python·算法·贪心算法