Edu Codeforces Round 142 (Rated for Div. 2)-D. Fixed Prefix Permutations-置换、字典树

题目:https://codeforces.com/problemset/problem/1792/D


非常套路地,\(q_{p_j}\)看成映射就是\((p*q)(j)\),双射自然可逆,所以改成\(q(j)=p^{-1}(j)\)
题目里的每个置换长度都不超过10(其实大一点也没问题),查询相当于对每个\(p\)查询所有排列里,排列的逆和他最长公共前缀的长度是多少,直接放到字典树里查询就ok了(感觉这个D比C还简单x)

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define endl '\n'
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
using namespace std;
const int N=5e4+5;
const int M=15;
int n,m,cnt,pos[M];
int tr[N*10][M],p[N][M];
void insert(int *p,int len){
	int k=0;
	rep(i,1,len){
		if(!tr[k][p[i]])tr[k][p[i]]=++cnt;
		k=tr[k][p[i]];
	}
}
int query(int *p,int len){
	int k=0;
	rep(i,1,len){
		if(tr[k][p[i]])k=tr[k][p[i]];
		else return i-1;
	}
	return len;
}
int main(){
	fastio;
	int T;cin>>T;
	while(T--){
		cin>>n>>m;
		rep(i,1,n){
			rep(j,1,m){
				cin>>p[i][j];
				pos[p[i][j]]=j;
			}
			insert(pos,m);
		}
		rep(i,1,n)cout<<query(p[i],m)<<' ';
		cout<<endl;
		rep(i,0,cnt)rep(j,1,m)tr[i][j]=0;
		cnt=0;
	}
	return 0;
}
posted @ 2023-02-09 12:28  yoshinow2001  阅读(17)  评论(0编辑  收藏  举报