分析:
考场上只写了 O(n2) O ( n 2 ) 的算法
勉强加了一点小优化(区间长度从当前局部最优解开始枚举)
首先我们肯定是要把点按横坐标排序
枚举区间中出现的颜色种类(状态压缩)
没有出现的颜色不能再区间内,这些点把区间可以出现的位置划分成了若干小段,每段内部只有我们枚举的颜色
之后题解是这样描述的:
不是很明白怎么赋hash值
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll unsigned long longusing namespace std;const ll p=1e9+7;
const int N=100002;
struct node{int x,b;bool operator <(const node &a)const {return x<a.x; }
};
node a[N];
struct point{int x;ll v;bool operator <(const point &a)const {return v<a.v||(v==a.v&&x<a.x);}
};
point po[N];
int n,K,co[10],er[N],ans=0;
ll inv[10];void solve(int state) {int cnt,i,tot=0;memset(co,0,sizeof(co));for (i=0;i<8;i++)if (state&(1<<i)) co[i]=tot++;if (tot<K) return;for (i=1;i<=n;i++) {cnt=0;int o=0;ll now=0; //前缀和 while (i<=n&&(er[a[i].b]&state)) //有这种颜色 {o|=er[a[i].b];int w=co[a[i].b]; //离散后的颜色编号if (w<tot-1) now-=inv[w];if (w) now+=inv[w-1];cnt++;po[cnt].x=i;po[cnt].v=now; i++;} if (o^state) continue; //枚举的颜色没有都出现sort(po+1,po+1+cnt); int _=1;for (int j=2;j<=cnt;j++) {if (po[_].v==po[j].v)ans=max(ans,a[po[j].x].x-a[po[_].x+1].x);else _=j;}}
} void doit() {for (int i=(1<<8)-1;i>0;i--)solve(i);printf("%dn",ans);
}int main()
{//freopen("long.in","r",stdin);//freopen("long.out","w",stdout);scanf("%d%d",&n,&K);for (int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].b),a[i].b--;sort(a+1,a+1+n);er[0]=1;for (int i=1;i<8;i++) er[i]=er[i-1]<<1;inv[0]=1;for (int i=1;i<8;i++) inv[i]=inv[i-1]*p; //自然溢出 doit();return 0;
}
本文发布于:2024-01-30 21:46:36,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170662239923048.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |