原题解链接:https://ac.nowcoder.com/discuss/151166
因为是随机的,所以分块维护一下颜色即可。
当然用其他方法也可以,验题人表示还可以用一个存下所有的相同的段,每次把这一段分离出来,然后把这一段里面的相同段修改之后合并成一段。
#include <cstdio>
#include <bits/stdc++.h>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)
typedef long long ll;
const int maxn = 100005;
const ll INF = 1e18;
const ll mod=1e9+7;
const double eps = 1e-7;
int n,m,q,gap;
int a[maxn];
int num[maxn];
int tag[maxn];
int tree[maxn],bl[maxn];
void reset(int x)
{
if(tag[x]==-1) return;
for(int i=(x-1)*gap+1;i<=min(n,x*gap);i++) a[i]=tag[x];
tag[x]=-1;
}
void solve(int l,int r,int val)
{
reset(bl[l]);
for(int i=l;i<=min(bl[l]*gap,r);i++)
{
if(a[i]!=val) num[a[i]]--,num[val]++,a[i]=val;
}
if(bl[l]!=bl[r])
{
reset(bl[r]);
for(int i=(bl[r]-1)*gap+1;i<=r;i++)
{
if(a[i]!=val) num[a[i]]--,num[val]++,a[i]=val;
}
}
for(int i=bl[l]+1;i<=bl[r]-1;i++)
{
if(tag[i]!=-1)
{
if(tag[i]!=val) num[tag[i]]-=gap,num[val]+=gap,tag[i]=val;
}
else
{
for(int j=(i-1)*gap+1;j<=i*gap;j++)
{
if(a[j]!=val) num[a[j]]--,num[val]++,a[j]=val;
}
tag[i]=val;
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&q);
gap=sqrt(n*1.0);
mst(tag,-1);
mst(num,0);
for(int i=1;i<=n;i++) bl[i]=(i-1)/gap+1;
solve(1,n,1);
for(int i=1;i<=q;i++)
{
int x,y;
ll A,B;
scanf("%d%d%lld%lld",&x,&y,&A,&B);
ll S=num[x];
ll tmp1=(A+(S+B)*(S+B)%(ll)n)%(ll)n+1;
ll tmp2=(A+S*B%n*(S*B%n)%(ll)n)%(ll)n+1;
if(tmp1>tmp2) swap(tmp1,tmp2);
solve((int)tmp1,(int)tmp2,y);
}
int ans=0;
for(int i=1;i<=m;i++) ans=max(ans,num[i]);
printf("%d\n",ans);
}