题目链接:点击打开链接
题意:
第一行给出C, n, Q
开始有一个编号[0, C) 的全0序列。
下面Q行操作
status id (询问下标为id的值)
groupchange [l, r] val 把区间[l,r] 每次+1(或-1)val次,当区间中某一个点达到0或n时则操作停止,输出实际+1(或-1)的值
change id val 同上,只是单点操作。
思路:
裸线段树,维护区间最值和加个lazy标记就可以了
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <vector>
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if(x>9) pt(x/10);
putchar(x%10+'0');
}
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 50500;
const int inf = 1e8;
#define L(x) tree[x].l
#define R(x) tree[x].r
#define Max(x) tree[x].max
#define Min(x) tree[x].min
#define Lazy(x) tree[x].lazy
#define ls (id<<1)
#define rs (id<<1|1)
struct Node{
int l, r, min, max, lazy;
}tree[N<<4];
void Up(int id){
Max(id) = max(Max(ls), Max(rs));
Min(id) = min(Min(ls), Min(rs));
}
void Down(int id){
if(Lazy(id)){
Min(ls) += Lazy(id);
Min(rs) += Lazy(id);
Max(ls) += Lazy(id);
Max(rs) += Lazy(id);
Lazy(ls) += Lazy(id);
Lazy(rs) += Lazy(id);
Lazy(id) = 0;
}
}
void build(int l, int r, int id){
L(id) = l; R(id) = r;
Min(id) = Max(id) = 0;
Lazy(id) = 0;
if(l == r)return ;
int mid = (l+r)>>1;
build(l, mid, ls); build(mid+1, r, rs);
}
void updata(int l, int r, int val, int id){
if(l == L(id) && R(id) == r){
Max(id) += val;
Min(id) += val;
Lazy(id) += val;
return ;
}
Down(id);
int mid = (L(id) + R(id))>>1;
if(r <= mid)
updata(l, r, val, ls);
else if(mid < l)
updata(l, r, val, rs);
else {
updata(l, mid, val, ls);
updata(mid+1, r, val, rs);
}
Up(id);
}
int query_max(int l, int r, int id){
if(l == L(id) && R(id) == r)return Max(id);
Down(id);
int mid = (L(id)+R(id))>>1, ans;
if(r <= mid) ans = query_max(l, r, ls);
else if(mid < l) ans = query_max(l, r, rs);
else ans = max(query_max(l, mid, ls), query_max(mid+1, r, rs));
Up(id);
return ans;
}
int query_min(int l, int r, int id){
if(l == L(id) && R(id) == r)return Min(id);
Down(id);
int mid = (L(id)+R(id))>>1, ans;
if(r <= mid) ans = query_min(l, r, ls);
else if(mid < l) ans = query_min(l, r, rs);
else ans = min(query_min(l, mid, ls), query_min(mid+1, r, rs));
Up(id);
return ans;
}
int C, n, q;
struct Q{
char op;
int l, r, x;
void put(){printf(" (%c, %d, %d, %d)\n", op, l, r, x);}
}o[50500];
char s[20];
vector<int>G;
void input(){
G.clear();
for(int i = 0; i < q; i++)
{
scanf("%s", s);
o[i].op = s[0];
if(s[0] == 's')rd(o[i].l);
else if(s[0] == 'g'){
rd(o[i].l); rd(o[i].r); rd(o[i].x);
G.push_back(o[i].r);
}
else {
o[i].op = 'g';
rd(o[i].l); rd(o[i].x);
o[i].r = o[i].l;
}
G.push_back(o[i].l);
}
sort(G.begin(), G.end());
G.erase(unique(G.begin(), G.end()), G.end());
for(int i = 0; i < q; i++){
o[i].l = lower_bound(G.begin(), G.end(), o[i].l) - G.begin()+1;
if(o[i].op == 'g')
o[i].r = lower_bound(G.begin(), G.end(), o[i].r) - G.begin()+1;
}
// for(int i = 0; i < q; i++)o[i].put();
}
int main(){
int T;
while(~scanf("%d%d%d", &C, &n, &q)){
// printf("---%d,%d,%d\n", C, n, q);
input();
build(1, (int)G.size(), 1);
int l, r, x, tmp; char c;
for(int i = 0; i < q; i++){
c = o[i].op; l = o[i].l; r = o[i].r; x = o[i].x;
if(c == 's')
pt(query_min(l, l, 1));
else if(c == 'g')
{
if(x == 0){puts("0");continue;}
else if(x > 0){
tmp = query_max(l, r, 1);
// printf("max:%d\n", tmp);
x = min(x, n - tmp);
}
else {
tmp = query_min(l, r, 1);
// printf("min:%d\n", tmp);
x = max(x, -tmp);
}
updata(l, r, x, 1);
pt(x);
}
putchar('\n');
}
}
return 0;
}