P2564 [SCOI2009]生日礼物
two-pointers problem
There is a similar problem called "guanghuazhan". You can find it in my blog.
Obviously we can use two pointers. But the index is too large!
An easy solution: Li San Hua!!!
Keep all the information for each jewel and sort by the position. Now you can run our dear two-pointer!
Code:
#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn = 1000005;
const int INF = 0x3f3f3f3f;
struct Nodes
{
int pos, col;
} s[maxn];
int tot;
int cnt[65];
int n, k;
bool cmp(Nodes a, Nodes b)
{
return a.pos < b.pos;
}
int two_pointers()
{
int l = 1, r = 0, res = 0, ans = INF;// l and r refer to index in array s
memset(cnt, 0, sizeof cnt);
while(l <= n)
{
while(r < n && res < k)
{
r++;
if(++cnt[s[r].col] == 1) res++;
}
if(res == k) ans = std::min(ans, s[r].pos - s[l].pos);
if(--cnt[s[l].col] == 0) res--;
l++;
}
return ans;
}
int read()
{
int ans = 0, s = 1;
char ch = getchar();
while(ch > '9' || ch < '0'){ if(ch == '-') s = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0', ch = getchar();
return s * ans;
}
int main()
{
n = read(), k = read();
for(int i = 1; i <= k; i++)
{
int m = read();
while(m--)
{
s[++tot].pos = read();
s[tot].col = i;
}
}
std::sort(s + 1, s + tot + 1, cmp);
//for(int i = 1; i <= tot; i++) printf("%d %d\n", s[i].pos, s[i].col);
printf("%d\n", two_pointers());
return 0;
}