good-problems 12
1.D. Fixed Prefix Permutations
题解
对于每个排列p,能得到答案最大值等价于排列p与所有q能匹配的最长前缀.
对于前缀问题可以使用字典树(Trie)解决
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define ll long long
#define pa pair<int,int>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define YES {puts("YES");return;}
#define NO {puts("NO");return ;}
using namespace std;
const int maxn=1e6+101;
const int N=6e5+1010;
const int MOD=998244353;
const int inf=2147483647;
const double pi=acos(-1);
const double eps=1e-12;
ll read(){
ll x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
return x*f;
}
int tot,ch[maxn][12];
void insert(vector<int> a){
int u=0,lenth=a.size();
for(int i=0;i<lenth;i++){
int k=a[i];
if(!ch[u][k])ch[u][k]=++tot;
u=ch[u][k];
}
return;
}
int find(vector<int> a){
int u=0,lenth=a.size(),ans=0;
for(int i=0;i<lenth;i++){
int k=a[i];
if(!ch[u][k])break;
u=ch[u][k];ans++;
}
return ans;
}
void init(){
for(int i=0;i<=tot;i++)for(int j=0;j<=10;j++)ch[i][j]=0;
tot=0;return ;
}
void solve() {
init();
int n=read(),m=read();
vector<vector<int> > a(n,vector<int>(m)),b(n,vector<int>(m));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)a[i][j]=read()-1,b[i][a[i][j]]=j;
//b[i][j]表示第i个序列的j在b[i][j]的位置上
//插入b,跟a进行匹配
//为什么不插入a,跟b匹配,:因为用b来匹配无法保证前缀匹配(也就是匹配不是从头到尾的,中间不连续)
insert(b[i]);
}
for(int i=0;i<n;i++)cout<<find(a[i])<<" ";puts("");
return ;
}
signed main(){
int t=read();
while(t--)solve();
return 0;
}
2.E. Josuke and Complete Graph
题意:
题解:
设
首先我们可以知道
当 时都是满足条件的,因为
现在考虑 的情况
设 , 只要满足 的 都是满足条件的
一个一个找肯定是不行的
注意对于一定范围的g, 其 是相同的,不难想到整除分块
整除分块的时间复杂度为
因为整除分块的时间复杂度取决于不同 的个数
对于
对于
因此时间复杂度为
这道题的整除分块与普通不同,是上取整,只是[l,r]的获取方式不同
点击查看代码
void solve() {
int L=read(),R=read(),ans=max(0ll,R/2-L+1);
for(int l=1,r;l<L;l=r+1){
int f=(L+l-1)/l;r=l;
int lr=L/f,rc=L-1;
while(rc>=lr){
int mid=(lr+rc)>>1;
if((L+mid-1)/mid==f)lr=mid+1,r=mid;
else rc=mid-1;
}
ans+=max(0ll,min(r-l+1,R/(f+1)-l+1));
}
cout<<ans<<endl;
return ;
}
3.F. Timofey and Black-White Tree
题解
点击查看代码
void solve() {
int n=read();
vector<int>dis(n+1),c(n);
for(int i=0;i<n;i++)c[i]=read(),dis[i+1]=inf;
vector<vector<int> >G(n+1);
for(int i=1;i<n;i++){
int u=read(),v=read();
G[u].pb(v);G[v].pb(u);
}
int ans=inf;
for(int i=0;i<n;i++){
ans=min(ans,dis[c[i]]);
if(i)cout<<ans<<" ";
queue<int>q;q.push(c[i]);
dis[c[i]]=0;
while(!q.empty()){
int u=q.front();q.pop();
for(auto v: G[u]){
if(dis[u]+1<dis[v] && dis[u]+1<ans){
dis[v]=dis[u]+1;
q.push(v);
}
}
}
}
puts("");return ;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】