首页 > 代码库 > HDU 4973 A simple simulation problem. 线段树
HDU 4973 A simple simulation problem. 线段树
题意:
给定n长的序列 m个操作
序列默认为 1, 2, 3···n
操作1:D [l,r] 把[l,r]区间增长 :( 1,2,3,4 进行 D [1,3]变成 1,1,2,2,3,3,4 )
操作2:Q [l,r] 问区间[l,r] 上出现最多次数的数 的次数
线段树,维护每个区间的size 和叶子节点中最大的size
开始二分查找size的前缀和,逗了一场。。其实直接dfs就好了嘛 Orz
#include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std; inline void rd(long long &n){ n = 0; char c = getchar(); while(c < '0' || c > '9') c = getchar(); while(c >= '0' && c <= '9') n *= 10, n += (c - '0'),c = getchar(); } inline void pt(long long n){ int len = 0,data[20]; while(n) data[len++] = n%10, n /= 10; if(!len) data[len++] = 0; while(len--) putchar(data[len]+48); } #define N 51000 typedef long long ll; inline int Mid(int x, int y){return (x+y)>>1;} #define L(x) (x<<1) #define R(x) (x<<1|1) #define Lson(x) tree[x].l #define Rson(x) tree[x].r #define Siz(x) tree[x].siz #define Val(x) tree[x].val #define Lazy(x) tree[x].lazy #define Max(x) tree[x].maxsize struct node{ int l, r, val; ll siz, lazy, maxsize;//siz是区间内的点数 maxsize是区间内最大点数 ,val是点的值 }tree[N<<2]; ll mul[60]; void push_down(int id){ if(Lazy(id)) { Siz(L(id)) = Siz(L(id)) << Lazy(id); Siz(R(id)) = Siz(R(id)) << Lazy(id); Max(L(id)) *= mul[Lazy(id)]; Max(R(id)) *= mul[Lazy(id)]; Lazy(L(id)) += Lazy(id); Lazy(R(id)) += Lazy(id); Lazy(id) = 0; } } void push_up(int id){ Max(id) = max(Max(L(id)), Max(R(id))); Siz(id) = Siz(L(id)) + Siz(R(id)); } void build(int l, int r, int id){ Lson(id) = l; Rson(id) = r; Lazy(id) = 0; if(l == r){ Val(id) = l; Max(id) = Siz(id) = 1; return ; } int mid = Mid(l, r); build(l, mid, L(id)); build(mid+1, r, R(id)); push_up(id); } void updata_siz(int pos, ll he, int id){ push_down(id); if(Lson(id) == Rson(id)) { Siz(id) += he; Max(id) += he; return ; } int mid = Mid(Lson(id), Rson(id)); if(mid < pos) updata_siz(pos, he, R(id)); else updata_siz(pos, he, L(id)); push_up(id); } void updata_qujian(int l, int r, int id){ push_down(id); if(l == Lson(id) && Rson(id) == r){ Lazy(id) ++; Max(id) <<= 1LL; Siz(id) <<= 1LL; return ; } int mid = Mid(Lson(id), Rson(id)); if(mid < l) updata_qujian(l, r, R(id)); else if(r <= mid) updata_qujian(l, r, L(id)); else { updata_qujian(l, mid, L(id)); updata_qujian(mid+1, r, R(id)); } push_up(id); } ll query_siz(int l, int r, int id){ push_down(id); if(l == Lson(id) && Rson(id) == r) return Siz(id); int mid = Mid(Lson(id), Rson(id)); if(mid < l) return query_siz(l, r, R(id)); else if(r <= mid) return query_siz(l, r, L(id)); else return query_siz(l, mid, L(id)) + query_siz(mid+1, r, R(id)); } ll query_max(int l, int r, int id){ push_down(id); if(l == Lson(id) && Rson(id) == r) return Max(id); int mid = Mid(Lson(id), Rson(id)); if(mid < l) return query_max(l, r, R(id)); else if(r <= mid) return query_max(l, r, L(id)); else return max(query_max(l, mid, L(id)), query_max(mid+1, r, R(id))); } int n, m; int find(ll x, int id){ push_down(id); if(Lson(id) == Rson(id))return Val(id); if( x <= Siz(L(id))) return find(x, L(id)); return find(x-Siz(L(id)), R(id)); } char s[2]; ll l, r; int main() { mul[0] = 1; for(int i = 1; i < 60; i++)mul[i] = mul[i-1] * 2LL; int T, Cas = 1; scanf("%d", &T); while (T--) { scanf("%d %d",&n,&m); build(1, n, 1); printf("Case #%d:\n", Cas++); while(m--){ scanf("%s", s); rd(l); rd(r); int z = find(l, 1), y = find(r, 1); if(z==y) { if(s[0] == 'D') updata_siz(z, r-l+1, 1); else {pt(r-l+1);putchar('\n');} continue; } ll Lsize = query_siz(1, z, 1) - l+1, Rsize = r - query_siz(1, y-1, 1); if(s[0] == 'Q') { ll ans = max(Lsize, Rsize); if(z + 1 <= y -1) ans = max(ans, query_max(z+1, y-1, 1)); pt(ans); putchar('\n'); } else { updata_siz(z, Lsize, 1); updata_siz(y, Rsize, 1); if(z + 1 <= y -1) updata_qujian(z+1, y-1, 1); } } } return 0; } /* 99 10 99 D 1 4 Q 1 14 D 2 7 Q 1 20 D 3 8 Q 1 4 Q 1 12 Q 1 11 Q 10 17 D 1 3 D 1 3 Q 1 18 Q 1 33 D 1 33 D 1 33 D 1 99 D 1 99 Q 1 105 Q 1 200 Q 150 210 Q 75 113 D 1 10 Q 2 8 Q 2 50 D 90 200 Q 1 300 Q 2 50 Q 90 160 Q 45 65 Q 78 92 Q 100 200 ans: 2 4 4 8 7 5 10 10 105 160 50 39 7 49 71 21 15 101 */
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。