题目大意 :给定n个数列,第 i 个数列包含ki个不超过m的正整数,同一数列里的数互不相同。每一秒将n个数列中的数左移一个位置,每个数列第一个数则移到该数列最后,并在一张纸上记下每个数列的第一个数。10^100秒过后,对于所有的1<=x<=m,求x在纸上出现的最长的连续的一段长度,该段必须是同一秒中记下的数。 数据范围 :1 ≤ n, m ≤ 100 000,1 ≤ ki ≤ 40,∑ki<=200 000
solution: 对于每个 i, 相当于在子区间统计答案,考虑双指针。注意到一组同余方程如果有解,那么对于其中任意两个一定满足 a1+k1m1=a2+k2m2 有解,即 gcd(m1,m2)|a2-a1 。又因为 m_i<=40 ,所以暴力判断每种 m_i 不会超过 40 。因为如果有两个相同的模数的话,一定满足 a_i=a_j 。每次新加入一个模数判断之前是否出现过。小优化:对于 f[t2[i]]==1 的情况将模数 1~40 判断,否则说明之前判断过,直接跳过。时间复杂度 O(40nlog40) 。
#include <cstdio>
#include <algorithm>
#include <cstring>
#define ll long long
#define PII pair<int,int>
#define rd(x) scanf("%lld" ,&(x))
using namespace std;
const int mx=1e5 +5 ;
int n,Maxa,c[45 ],f[45 ];
int t1[mx],t2[mx],t3[mx],cnt;
ll a[mx],m[mx];
vector<PII> vec[mx];
ll gcd (ll x,ll y) {
return y==0 ?x:gcd (y,x%y);
}
ll lcm (ll x,ll y) {
if (x==0 ||y==0 ) return x^y;
return x/gcd (x,y)*y;
}
ll fmul (ll x,ll y,ll z) {
x%=z,y%=z; if (y<0 ) x=-x,y=-y;
ll sum (0 ) ;
for (;y;y>>=1 ) {
if (y&1 ) sum=(sum+x)%z;
x=(x+x)%z;
}
return sum;
}
ll fpow (ll x,ll y,ll z) {
x%=z;
ll mul (1 ) ;
for (;y;y>>=1 ) {
if (y&1 ) mul=mul*x%z;
x=x*x%z;
}
return mul;
}
ll inv (ll x,ll y) {
if (y==1 ) return 0 ;
return fpow (x,y-2 ,y);
}
void exgcd (ll &x,ll &y,ll a,ll b,ll &d) {
if (b==0 ) {
x=1 ,y=0 ,d=a;
}
else {
exgcd (y,x,b,a%b,d);
y-=x*(a/b);
}
}
bool excrt () {
for (int i=1 ;i<=n;i++) {
if (a[i]>=m[i]) return 1 ;
}
for (int i=2 ;i<=n;i++) {
ll tmp=((a[i]-a[1 ])%m[i]+m[i])%m[i];
ll k1,k2,d; exgcd (k1,k2,m[1 ],m[i],d);
if (tmp%d) return 1 ;
k1=(k1%(m[i]/d)*(tmp/d)%(m[i]/d)+(m[i]/d))%(m[i]/d);
ll M=m[1 ]/d*m[i];
a[1 ]=(a[1 ]+m[1 ]*k1%M)%M;
m[1 ]=M;
}
return 0 ;
}
ll solve (int id) {
cnt=0 ;
for (auto y:vec[id]) {
t1[++cnt]=y.first,t2[cnt]=m[y.first],t3[cnt]=y.second;
}
int j=1 ,res=0 ;
for (int i=1 ;i<=cnt;i++) {
if (t1[i]!=t1[i-1 ]+1 ) {
for (;j<i;f[t2[j]]--,j++);
}
if (f[t2[i]]&&c[t2[i]]!=t3[i]) {
for (;j<i&&f[t2[i]];f[t2[j]]--,j++);
}
f[t2[i]]++,c[t2[i]]=t3[i];
if (f[t2[i]]==1 ) {
for (int k=1 ;k<=40 ;k++) {
if (f[k]&&(t3[i]-c[k])%gcd (t2[i],k)) {
for (;j<i&&f[k];f[t2[j]]--,j++);
}
}
}
res=max (res,i-j+1 );
}
for (;j<=cnt;f[t2[j]]--,j++);
return res;
}
int main () {
scanf ("%d%d" ,&n,&Maxa);
for (int i=1 ;i<=n;i++) {
scanf ("%lld" ,&m[i]);
for (int j=0 ;j<m[i];j++) {
int x; scanf ("%d" ,&x);
vec[x].push_back (make_pair (i,j));
}
}
for (int i=1 ;i<=Maxa;i++) {
printf ("%lld\n" ,solve (i));
}
}
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」