题目链接:点击打开链接
题意:
第一行给出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; }