题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=600
树状数组+离散化:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define maxn 300005
#define lowbit(x) (x&-x)
struct node
{
int val, pos;
bool operator < (const node& n)const
{
return val<n.val;
}
}mm[maxn];
int real[maxn], fen[maxn];
void add(int x, int n, int d)
{
while (x<=n)
{
fen[x] += d;
x += lowbit(x);
}
}
int sum(int x)
{
int Sum = 0;
while (x>0)
{
Sum += fen[x];
x -= lowbit(x);
}
return Sum;
}
int main()
{
int ncase, n, m, a, b, N, x;
scanf("%d", &ncase);
while (ncase--)
{
scanf("%d%d", &n, &m);
N = n*2 + m;
for (int i=1; i<=N; i++)
{
scanf("%d", &a);
mm[i].val = a;//需要离散化的点
mm[i].pos = i;
}
sort(mm+1, mm+N+1);
x = 0;
for (int i=1; i<=N; ++i)//离散化
{
if (mm[i].val != mm[i-1].val)
real[ mm[i].pos ] = ++x;
else
real[ mm[i].pos ] = x;
}
memset(fen, 0, sizeof(fen));
for (int i=1; i<=2*n; i+=2)
{
add(real[i], x+1, 1);
add(real[i+1]+1, x+1, -1);
}
for (int i=n*2+1; i<=N; ++i)
printf("%d\n", sum(real[i]));
}
return 0;
}
离散化+线段树:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 300005
int real[maxn];
struct node
{
int val, pos;
bool operator < (const node& n)const
{
return val<n.val;
}
}mm[maxn];
struct Node
{
int l, r, d;
}v[maxn<<2];
void pushdown(int n)
{
if (v[n].d)
{
v[n<<1].d += v[n].d;
v[n<<1|1].d += v[n].d;
v[n].d = 0;
}
}
void build(int l, int r, int n)
{
v[n].l = l, v[n].r = r, v[n].d = 0;
if (l==r)
return ;
int mid = (l+r)>>1;
build(l, mid, n<<1);
build(mid+1, r, n<<1|1);
}
void update(int l, int r, int n, int d)
{
if (l<=v[n].l && v[n].r<=r)
{
v[n].d += d;
return ;
}
pushdown(n);
int mid = (v[n].l + v[n].r) >> 1;
if (r<=mid)
update(l, r, n<<1, d);
else if (l>mid)
update(l, r, n<<1|1, d);
else
{
update(l, mid, n<<1, d);
update(mid+1, r, n<<1|1, d);
}
}
int query(int x, int n)
{
if (v[n].l==x && v[n].r==x)
return v[n].d;
pushdown(n);
int mid = (v[n].l + v[n].r) >> 1;
if (x<=mid)
return query(x, n<<1);
return query(x, n<<1|1);
}
int main()
{
int ncase, n, m, a, b, N, x;
scanf("%d", &ncase);
while (ncase--)
{
scanf("%d%d", &n, &m);
N = n*2 + m;
for (int i=1; i<=N; ++i)
{
scanf("%d", &a);
mm[i].val = a;//需要离散化的点
mm[i].pos = i;
}
sort(mm+1, mm+N+1);
x = 0;
for (int i=1; i<=N; ++i)//离散化
{
if (mm[i].val != mm[i-1].val)
real[ mm[i].pos ] = ++x;
else
real[ mm[i].pos ] = x;
}
build(1, x, 1);
for (int i=1; i<=2*n; i+=2)
update( real[i], real[i+1], 1, 1 );
for (int i=2*n+1; i<=N; i++)
printf("%d\n", query( real[i], 1 ));
}
return 0;
}
hash:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define N 100000
int a[N], b[N];
int main()
{
int ncase, n, m, x, y;
scanf("%d", &ncase);
while (ncase--)
{
scanf("%d%d", &n, &m);
memset(a, 0, sizeof(a));
memset(b, 0,sizeof(b));
for (int i=0; i<n; i++)
{
scanf("%d%d", &x, &y);
if (y<=N)
for (int j=x; j<=y; ++j)
++a[j];
else if (x>N)
for (int j=x%N, t=y%N; j<=t; ++j)
++b[j];
else
{
for (int j=x; j<=N; ++j)
++a[j];
for (int j=0, t=y%N; j<=t; ++j)
++b[j];
}
}
while (m--)
{
scanf("%d", &x);
if (x<=N)
printf("%d\n", a[x]);
else
printf("%d\n", b[y%N]);
}
}
return 0;
}