E. Cow and Treats
分析:想一想就知道每一边的牛爱吃的草都不一样
枚举每一个元素作为左边到达的最远距离,再看右边能不能有一个吃一样草的,然后再看其他味道的草,a只能放在左边,b只能放在右边,c两边都可以,然后判断更新答案;
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=5007;
const int mod=1e9+7;
const ll INF=1e18;
int g[maxn];
struct node{int l,r;};
vector<node> p[maxn];
void rua()
{
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&g[i]);
for(int i=1;i<=m;i++)
{
int x,y;scanf("%d%d",&x,&y);
int tmp=0,l=-1,r=-1;
for(int j=1;j<=n;j++)
{
if(x==g[j]) tmp++;
if(tmp==y) {l=j;break;}
}
tmp=0;
for(int j=n;j>0;j--)
{
if(x==g[j]) tmp++;
if(tmp==y) {r=j;break;}
}
if(l!=-1) p[x].pb({l,r});
}
int num=0;ll sum=1;
for(int i=1;i<=n;i++)
if(p[i].size()>0) {num++;sum=(sum*p[i].size())%mod;}
for(int i=1;i<=n;i++)for(auto x:p[i])
{
int ff=x.l,tmpnum=1,cnt=0;
ll tmpsum=1;
for(auto y:p[i])
{
if(y.l==x.l && y.r==x.r) continue;
if(y.r>ff) cnt++;
}
if(cnt) tmpnum++,tmpsum=(tmpsum*cnt)%mod;
for(int j=1;j<=n;j++) if(i!=j)
{
int a=0,b=0,c=0;
for(auto y:p[j])
{
if(y.l<ff && y.r>ff) c++;
else if(y.l<ff) a++;
else if(y.r>ff) b++;
}
ll res=(a*b%mod+a*c%mod+b*c%mod+c*(c-1)%mod)%mod;
if(res>0) tmpnum+=2,tmpsum=(tmpsum*res)%mod;
else if(a+b+c) tmpnum++,tmpsum=(tmpsum*(a+b+2*c)%mod)%mod;
}
if(tmpnum>num) num=tmpnum,sum=tmpsum;
else if(tmpnum==num) sum=(sum+tmpsum)%mod;
}
printf("%d %lld\n",num,sum);
}
int main()
{
rua();
return 0;
}