秋实大哥与小朋友
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
秋实大哥以周济天下,锄强扶弱为己任,他常对天长叹:安得广厦千万间,大庇天下寒士俱欢颜。
所以今天他又在给一群小朋友发糖吃。
他让所有的小朋友排成一行,从左到右标号。在接下去的时间中,他有时会给一段区间的小朋友每人 v v颗糖,有时会问第 x x个小朋友手里有几颗糖。
这对于没上过学的孩子来说实在太困难了,所以你看不下去了,请你帮助小朋友回答所有的询问。
Input
第一行包含两个整数 n n, m m,表示小朋友的个数,以及接下来你要处理的操作数。
接下来的 m m行,每一行表示下面两种操作之一:
0 l r v : 表示秋实大哥给[l,r]这个区间内的小朋友每人v颗糖 1 x : 表示秋实大哥想知道第x个小朋友手里现在有几颗糖
1≤m,v≤100000 1≤m,v≤100000, 1≤l≤r≤n 1≤l≤r≤n, 1≤x≤n 1≤x≤n, 1≤n≤100000000 1≤n≤100000000。
Output
对于每一个 1 1 x x操作,输出一个整数,表示第 x x个小朋友手里现在的糖果数目。
Sample input and output
Sample Input | Sample Output |
---|---|
3 4 0 1 3 1 1 2 0 2 3 3 1 3 | 1 4 |
解题思路:乍一看题目很简单,但是数据规模太大,所以需要使用到离散化。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
#define maxn 200005
set<int>jud;
long long tr[maxn];
int point[maxn];
//是否可以改掉,只用set而不用再开一个数组?
int size = 0;
struct operate
{
int op, l, r, v;
operate(int op, int l, int r, int v)
{
this->op = op; this->l = l;
this->r = r; this->v = v;
}
};
queue<operate>operque;
void update(int l, int r, int val)
{
for (int i = r; i > 0; i -= i&(-i))
tr[i] += val;
for (int i = l - 1; i > 0; i -= i&(-i))
tr[i] += (-val);
}
long long query(int idx)
{
long long sum = 0;
while (idx <= size)
{
sum += tr[idx];
idx += idx&(-idx);
}
return sum;
}
int main()
{
int l = 0, r = 0, x = 0;
int n = 0, m = 0, bl = 0, v = 0;
char op[10] = { '\0' };
char fst[10] = { '\0' };
memset(point, 0, sizeof(point));
memset(tr, 0, sizeof(tr));
gets(fst);
sscanf(fst,"%d %d", &n, &m);
while (m--)
{
gets(op);
if (op[0] == '0')
{
sscanf(op, "%d %d %d %d", &bl, &l, &r, &v);
if (!jud.count(l))
{
jud.insert(l);
point[++size] = l;
}
if (!jud.count(r))
{
jud.insert(r);
point[++size] = r;
}
operque.push(operate(bl, l, r, v));
}
else if (op[0] == '1')
{
sscanf(op, "%d %d", &bl, &x);
if (!jud.count(x))
{
jud.insert(x);
point[++size] = x;
}
operque.push(operate(bl, 0, 0, x));
}
}
sort(point + 1, point + 1 + size);
while (!operque.empty())
{
operate temp = operque.front(); operque.pop();
if (temp.op & 1)
{
int pos = lower_bound(point + 1, point + 1 + size, temp.v) - point;
printf("%lld\n", query(pos));
}
else
{
int left = lower_bound(point + 1, point + 1 + size, temp.l) - point;
int right = lower_bound(point + 1, point + 1 + size, temp.r) - point;
update(left, right, temp.v);
}
}
return 0;
}
题目链接: 点击打开链接http://acm.uestc.edu.cn/#/problem/show/1059