由于刚刚练习了线段树,直接第一反应用线段树敲了,WA,把数据改成long ,WA,最后才发现错在没有考虑0不在线段树的节点上,所以又在输出时增加判断包含0的情况。最后超大空间超长时间AC。
而且读题发现All the integers are distinct 。。。忽略了这句话
Problem A: How many Points
Description
Welcome to NBUT Summer Trainning For ACM, I want you guys will enjoy this experiment.
But firstly, your foolish captain Alex is thinking about an easy problem(to others), he can't solve it, so he asks you for help. Maybe you will suspect how he can become the captain?
Givn n points and m segments in X-Axes, for each segment, I want to know how many points in this segment.
A point Pi wil lie in a segment AB, if Ai <= Pi <= Bi.
Input
Input starts with an integer T (≤ 5), denoting the number of test cases.
Each test case starts with two integers n (n <= 100000) and m (m <= 100000)
Then next line contains n space separated integers denoting the points in ascending order. All the integers are distinct and each of them range in [0, 100000].
Output
For each case, print the case number in a single line. Then for each segment, print the number of points that lie in that segment.
Sample Input
1
5 3
1 3 4 5 6
0 7
1 2
1 6
Sample Output
Case 1:
5
1
5
线段树冗杂代码:
#include <stdio.h>
#include <string.h>
struct node
{
long int l,r;
long int sum;
}tree[100000 * 4];
long int num[100000 + 10];
void build(long int p,long int l,long int r)
{
tree[p].l = l;
tree[p].r = r;
if(l == r)
{
tree[p].sum = num[l];
return ;
}
long int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
tree[p].sum = tree[p << 1].sum + tree[p << 1| 1].sum;
}
long int query(long int p,long int ql,long int qr)
{
if(tree[p].l == ql && tree[p].r == qr)
return tree[p].sum;
if(tree[p].l == tree[p].r)
{
return tree[p].sum;
}
long int mid = (tree[p].l + tree[p].r) >> 1;
if(mid >= ql && mid < qr)
{
return query(p << 1, ql, mid) + query(p << 1 | 1, mid+1, qr);
}
if(mid >= qr)
return query(p << 1, ql, qr);
if(mid < ql)
return query(p << 1 | 1, ql, qr);
}
int main()
{
int t,nn = 1;
scanf("%d", &t);
while(t--)
{
long int n,m;
scanf("%ld%ld", &n, &m);
memset(num, 0, sizeof(num));
long int mm = 0;
for(long int i = 0; i < n; i++)
{
long int a;
scanf("%ld", &a);
if(mm < a) mm = a;
num[a]++;
}
build(1,1,mm);
printf("Case %d:\n", nn++);
while(m--)
{
long int a,b,c=0;
scanf("%ld%ld", &a, &b);
if(a <= 0 )
{
c = num[0];a = 1;
}
if(b >= 1)
c += query(1,a,b);
printf("%ld\n", c);
}
}
return 0;
}
队友用数组搞定:
#include <stdio.h>
#include <string.h>
int number[100005];
int s[100005];
int main()
{
int t;
scanf("%d", &t);
int k = 1;
while(t--)
{
memset(number, 0, sizeof(number));
int n, m;
scanf("%d%d", &n, &m);
int max = -1;
int min = 10000000;
for (int i = 0; i < n; ++i)
{
scanf("%d", &s[i]);
if (s[i] > max)
{
max = s[i];
}
if (s[i] < min)
{
min = s[i];
}
number[s[i]]++;
}
for (int i = 1; i <= max; ++i)
{
number[i] += number[i - 1];
}
printf("Case %d:\n", k++);
int a, b;
for (int i = 0; i < m; ++i)
{
scanf("%d%d", &a, &b);
if (a < min)
{
a = min;
}
if (b > max)
{
b = max;
}
if (number[a] == 0)
printf("%d\n", number[b] - number[a]);
else
{
if (a == 0)
printf("%d\n", number[b]);
else
printf("%d\n", number[b] - number[a - 1]);
}
}
}
return 0;
}
神超的代码:
/*************************************************************************
> File Name: LightOJ1088.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年07月07日 星期二 15时28分38秒
************************************************************************/
#include <iostream>
#include <fstream>
#include <cstring>
#include <climits>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <ctime>
#include <list>
#include <map>
#include <set>
#include <utility>
#include <sstream>
#include <complex>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <functional>
#include <algorithm>
using namespace std;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int, int> PLL;
const LL INF = (1LL << 60);
const int N = 100110;
int Arr[N];
int Find1(int n, int val)
{
if (Arr[1] >= val) {
return 1;
}
int ans, l = 1, r = n, mid;
while (l <= r)
{
mid = (l + r) >> 1;
if (Arr[mid] >= val)
{
ans = mid;
r = mid - 1;
}
else
{
l = mid + 1;
}
}
return ans;
}
int Find2(int n, int val)
{
if (val >= Arr[n]) {
return n;
}
int l = 1, r = n, mid, ans;
while (l <= r)
{
mid = (l + r) >> 1;
if (Arr[mid] <= val)
{
ans = mid;
l = mid + 1;
}
else
{
r = mid - 1;
}
}
return ans;
}
int main() {
int t, icase = 1;
// freopen("data.in", "r", stdin);
// freopen("data.out", "w", stdout);
double t1 = clock();
scanf("%d", &t);
while (t--)
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)
{
scanf("%d", &Arr[i]);
}
int l, r;
printf("Case %d:\n", icase++);
while (m--)
{
scanf("%d%d", &l, &r);
if (r < Arr[1] || l > Arr[n]) {
printf("0\n");
continue;
}
l = Find1(n, l);
r = Find2(n, r);
printf("%d\n", r - l + 1);
}
}
// double t2 = clock();
// printf("%.12f\n", (t2 - t1) / CLOCKS_PER_SEC * 1000);
return 0;
}