解析:
比较水的一道线段树问题,注意分母不能为负数(在这里wa了好多次)。
AC代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#define ls o*2
#define rs o*2+1
using namespace std;
typedef long long ll;
const int N = 100005;
ll sumv[N<<2], setv[N<<2];
ll _sumv, _setv;
ll gcd(ll a, ll b) {
if(b == 0) return a;
else return gcd(b, a%b);
}
inline void maintain(int o) {
sumv[o] = sumv[ls] + sumv[rs];
setv[o] = setv[ls] + setv[rs];
}
void build(int o, int L, int R) {
if(L == R) {
sumv[o] = setv[o] = 0;
return ;
}
int M = (L+R)/2;
build(ls, L, M);
build(rs, M+1, R);
maintain(o);
}
int pos;
ll val;
void modify(int o, int L, int R) {
if(L == R) {
setv[o]++, sumv[o] += val;
return ;
}
int M = (L+R)/2;
if(pos <= M) modify(ls, L, M);
else modify(rs, M+1, R);
maintain(o);
}
int ql, qr;
void query(int o, int L, int R) {
if(ql <= L && R <= qr) {
_sumv += sumv[o];
_setv += setv[o];
return ;
}
int M = (L+R)/2;
if(ql <= M) query(ls, L, M);
if(qr > M) query(rs, M+1, R);
}
int main() {
int n, q;
while(scanf("%d%d", &n, &q) != EOF) {
build(1, 0, n+10);
int cmd;
while(q--) {
scanf("%d", &cmd);
if(cmd == 1) {
scanf("%d%lld", &pos, &val);
modify(1, 0, n);
}else {
scanf("%d%d", &ql, &qr);
_sumv = _setv = 0;
query(1, 0, n);
if(_setv == 0)
puts("Error!");
else {
ll g = gcd(_sumv, _setv);
if(_sumv == 0)
puts("0/1");
else {
ll de = _sumv/g, nu = _setv/g;
if(de * nu < 0) {
if(nu < 0) {
printf("%lld/%lld\n", -de, -nu);
}else {
printf("%lld/%lld\n", de, nu);
}
}else
printf("%lld/%lld\n", de, nu);
}
}
}
}
}
return 0;
}