bzoj 2743 分类: bzoj 2015-08-07 18:22 9人阅读 评论(0) 收藏
这道题的方法虽然应用不广,但很有意思。
主要是维护起始点固定时,每个结束点的答案
每个点记录下一个与它颜色相同的点的位置,记为next[]。
首先对于所有首次出现的点 x,将 next[x] ~ n 的答案都增加 1
然后就得到了当起始点为1时,每个结束点的答案。
如果起始点pos向右移动,next[pos]~next[next[pos]] - 1 的答案都减少 1
对答案改变的的操作可以用树状数组。。。
本来想用莫队水过的。。。然而TLE了
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <vector>
#include <utility>
#include <stack>
#include <queue>
#include <iostream>
#include <algorithm>
template<class Num>void read(Num &x)
{
char c; int flag = 1;
while((c = getchar()) < '0' || c > '9')
if(c == '-') flag *= -1;
x = c - '0';
while((c = getchar()) >= '0' && c <= '9')
x = (x<<3) + (x<<1) + (c-'0');
x *= flag;
return;
}
template<class Num>void write(Num x)
{
if(x < 0) putchar('-'), x = -x;
static char s[20];int sl = 0;
while(x) s[sl++] = x%10 + '0',x /= 10;
if(!sl) {putchar('0');return;}
while(sl) putchar(s[--sl]);
}
const int size = 1e6 + 5, maxm = size, maxn = size;
int n, c, m, a[maxn];
int next[size], fir[size], tree[maxn];
struct type_query
{
int id, l, r, ans;
void scan(int __i)
{
id = __i, read(l), read(r);
}
}query[maxm];
bool cmp(const type_query &a, const type_query &b){ return a.l < b.l;}
bool cmpid(const type_query &a, const type_query &b){ return a.id < b.id;}
#define lowbit(x) ((x)&-(x))
void add(int x,int val)
{
if(!x) return;
while(x <= n)
{
tree[x] += val;
x += lowbit(x);
}
}
int count(int x)
{
int ret = 0;
while(x > 0)
{
ret += tree[x];
x -= lowbit(x);
}
return ret;
}
#undef lowbit
int main()
{
#ifndef ONLINE_JUDGE
freopen("2743.in","r",stdin);
freopen("2743.out","w",stdout);
#endif
read(n), read(c), read(m);
for(int i = 1; i <= n; i++) read(a[i]);
for(int i = 1; i <= m; i++) query[i].scan(i);
std::sort(query + 1, query + m + 1, cmp);
for(int i = n; i >= 1; i--)
next[i] = fir[a[i]], fir[a[i]] = i;
for(int i = 1; i <= n; i++)
if(fir[a[i]] == i) add(next[i], 1);
for(int i = 1, pos = 1; i <= m; i++)
{
while(pos < query[i].l)
{
add(next[pos], -1);
add(next[next[pos]], 1);
pos ++;
}
query[i].ans = count(query[i].r);
}
std::sort(query + 1, query + m + 1, cmpid);
for(int i = 1; i <= m; i++)
write(query[i].ans), puts("");
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。