hdu5306 hdu3954 cf438D

///链接:https://codeforces.com/problemset/problem/438/D
/*题意: 三种操作,1,求和,2,区间取模,3,单点修改
  题解:线段树,考虑保存最大值,如果t大于当前最大值了,就一定不要继续递归了
*/

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cctype>
#include <queue>
#include <stdlib.h>
#include <cstdlib>
#include <math.h>
#include <set>
#include"queue"
#include <vector>
#define inf 107374182
#define M 10010001
#define ll long long
#define PII pair<int,int>
using namespace std;
inline int read(){
    int s = 0, w = 1; char ch = getchar();
    while(ch < '0' || ch > '9')   { if(ch == '-') w = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') { s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar(); }
    return s * w;
}

const int N = 1000010;
int n,m;
int root,lson[N << 2],rson[N << 2],tot,maxx[N << 2],val[N << 2];
ll sum[N << 2];
int a[N];

void push_up(int rt){
    sum[rt] = sum[lson[rt]] + sum[rson[rt]];
    maxx[rt] = max(maxx[lson[rt]],maxx[rson[rt]]);
}
void Build_Tree(int &rt,int l,int r){
  rt = ++ tot;sum[rt] = 0; maxx[rt] =-1;
  if(l == r){
    sum[rt] = maxx[rt] = val[rt] = a[l];
    return ;
  }
  int mid = (l + r) >> 1;
  Build_Tree(lson[rt],l,mid);
  Build_Tree(rson[rt],mid + 1,r);
  push_up(rt);
}

void Update(int rt,int L,int R,int pos,int x){
   if(L == R){
     val[rt] = x;
     sum[rt] = maxx[rt] = x;
     return ;
   }
   int mid = (L + R) >> 1;
   if(pos <= mid) Update(lson[rt],L,mid,pos,x);
   else Update(rson[rt],mid + 1,R,pos,x);
   push_up(rt);
}
void Update_mod(int rt,int L,int R,int l,int r,int x){
    if(maxx[rt] < x)return ;
 //   if(l <= L && r >= R && maxx[rt] < x) return ;
    if(L == R){
        val[rt] %= x;maxx[rt] = sum[rt] = val[rt]; return ;
    }
    int mid = (L + R) >> 1;
    if(l <= mid) Update_mod(lson[rt],L,mid,l,r,x);
    if(r > mid) Update_mod(rson[rt],mid + 1,R,l,r,x);
    push_up(rt);
}
ll query(int rt,int L,int R,int l,int r){
  //  if(R < L) return 0;
    if(l <= L && r >= R) return sum[rt];
    int mid = (L + R) >> 1;
    ll ans = 0;
    if(l <= mid) ans = ans + query(lson[rt],L,mid,l,r);
    if(r > mid) ans = ans + query(rson[rt],mid + 1,R,l,r);
    return ans;
}

int main(){
    n = read(); m = read();
    for(int i = 1 ;i <= n; i ++) a[i] = read();
    Build_Tree(root,1,n);
    while(m --){
         int op = read(); int l = read(),r = read();
         if(op == 1) {
            ll ans = query(root,1,n,l,r);
            printf("%lld
",ans);
         }
         if(op == 2) {
            int t = read();
            Update_mod(root,1,n,l,r,t);
         }
         if(op == 3){
            Update(root,1,n,l,r);
         }
    }
}

  


///链接:http://acm.hdu.edu.cn/showproblem.php?pid=5306 /*题意 对一个序列执行查询和修改三种操作,其中修改比较奇特; 题解:这个如果暴力执行修改操作,那么一定会超时,所以我们考虑引入第二小的值,从而达到目的。减少复杂度 */ #include <iostream> #include <string> #include <cstring> #include <algorithm> #include <cstdio> #include <cctype> #include <queue> #include <stdlib.h> #include <cstdlib> #include <math.h> #include <set> #include"queue" #include <vector> #define inf 107374182 #define M 10010001 #define ll long long #define PII pair<int,int> using namespace std; inline int read(){ int s = 0, w = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar(); } return s * w; } const int N = 1000010; ll sum[N<<4];int n,m; int max_val[N << 2],seg[N << 2],num[N << 2],tot,root,lson[N << 2],rson[N << 2]; int a[N]; void push_up(int rt){ sum[rt] = sum[lson[rt]] + sum[rson[rt]]; max_val[rt] = max(max_val[lson[rt]],max_val[rson[rt]]); if(max_val[lson[rt]] == max_val[rson[rt]]){ num[rt] = num[lson[rt]] + num[rson[rt]]; seg[rt] = max(seg[lson[rt]],seg[rson[rt]]); return ; } if(max_val[rt] == max_val[lson[rt]]){ num[rt] = num[lson[rt]]; seg[rt] = max(seg[lson[rt]],max_val[rson[rt]]); return ; } num[rt] = num[rson[rt]]; seg[rt] = max(seg[rson[rt]],max_val[lson[rt]]); return ; } void Tag_dwon(int rt,int maxx){ if(max_val[rt] <= maxx) return ; sum[rt] = sum[rt] - (ll)num[rt] * (max_val[rt] - maxx); max_val[rt] = maxx; } void push_down(int rt){ Tag_dwon(lson[rt],max_val[rt]); Tag_dwon(rson[rt],max_val[rt]); } void Build_Tree(int &rt,int l,int r){ rt = ++ tot; max_val[rt] = seg[rt] = -1; num[rt] = sum[rt] = 0; if(l == r) { num[rt] = 1; sum[rt] = a[l]; max_val[rt] = a[l]; return ; } int mid = (l + r) >> 1; Build_Tree(lson[rt],l,mid); Build_Tree(rson[rt],mid + 1,r); push_up(rt); } void Update(int rt,int L,int R,int l,int r,int val){ if(L > R) return ; if(max_val[rt] <= val) return ; if(l <= L && r >= R && val > seg[rt]){ sum[rt] = sum[rt] - (ll)num[rt] * (max_val[rt] - val); max_val[rt] = val; return ; } push_down(rt); int mid = (L + R) >> 1; if(l <= mid) Update(lson[rt],L,mid,l,r,val); if(r > mid) Update(rson[rt],mid + 1,R,l,r,val); push_up(rt); } int get_maxx(int rt,int L,int R,int l,int r){ if(L > R) return 0; if(l <= L && r >= R) { return max_val[rt]; } push_down(rt); int mid = (L + R) >> 1; int maxx = 0; if(l <= mid) maxx = max(maxx,get_maxx(lson[rt],L,mid,l,r)); if(r> mid) maxx = max(maxx,get_maxx(rson[rt],mid + 1,R,l,r)); return maxx; } ll get_sum(int rt,int L,int R,int l,int r){ if(L > R) return 0; if(l <= L && r >= R) { return sum[rt]; } push_down(rt); int mid = (L + R) >> 1; ll ans = 0; if(l <= mid) ans += get_sum(lson[rt],L,mid,l,r); if(r > mid) ans += get_sum(rson[rt],mid + 1,R,l,r); return ans; } void init(){ tot = 0; } int main(){ int T = read(); while(T --){ n = read(); m = read(); init(); for(int i = 1; i <= n; i ++) a[i] = read(); Build_Tree(root,1,n); while(m --){ int op = read(),l = read(),r = read(); if(op == 0){ int t = read(); Update(root,1,n,l,r,t); } else if(op == 1){ printf("%d ",get_maxx(root,1,n,l,r)); } else { printf("%lld ",get_sum(root,1,n,l,r)); } } } }

  

///链接:http://acm.hdu.edu.cn/showproblem.php?pid=3954
/*题意 打怪升级,但是每次升级的经验值为k(等级)*e(i);
  题解:如果每个结点都进行修改的话,肯定会超时的,所以我们需要考虑如何打懒惰标记。懒惰标记的本质
  还是减少修改次数,我们可以对每个结点维护一个当前区间所需要的的最小经验值;如果这次打怪加的经验都不足以
  让这个区间内的结点升级,那我们就没有必要再往下进行更新了。同时,我们可以通过一个小的数学操作
  ((升级经验要求) - 当前经验)/ 等级 在向上取整,则可以消除等级对我们的懒惰标记的影响。
  所以每个结点需要维护三个值:
        当前区间内升级的最小经验值,当前区间内的最大经验值,当前区间内的最大等级
*/

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cctype>
#include <queue>
#include <stdlib.h>
#include <cstdlib>
#include <math.h>
#include <set>
#include"queue"
#include <vector>
#define inf 107374182
#define M 10010001
#define ll long long
#define PII pair<int,int>
using namespace std;
inline int read(){
    int s = 0, w = 1; char ch = getchar();
    while(ch < '0' || ch > '9')   { if(ch == '-') w = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') { s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar(); }
    return s * w;
}

const int N = 1000010;
int n,m;
int root,lson[N << 2],rson[N << 2],tot,max_val[N << 2],min_val[N << 2],max_top[N << 2];
int laze[N << 2],a[N];

void push_up(int rt){
    max_val[rt] = max(max_val[lson[rt]],max_val[rson[rt]]);
    min_val[rt] = min(min_val[lson[rt]],min_val[rson[rt]]);
    max_top[rt] = max(max_top[lson[rt]],max_top[rson[rt]]);
}
void push_down(int rt){
    if(laze[rt] == 0) return ;
    laze[lson[rt]] += laze[rt]; laze[rson[rt]] += laze[rt];
    max_val[lson[rt]] += laze[rt] * max_top[lson[rt]]; max_val[rson[rt]] += laze[rt] * max_top[rson[rt]];
    min_val[lson[rt]] -= laze[rt]; min_val[rson[rt]] -= laze[rt];
    laze[rt] = 0;
}
void Build_Tree(int &rt,int l,int r){
  rt = ++ tot; laze[rt] = 0;
  if(l == r){
    max_val[rt] = 0; max_top[rt] = 1; laze[rt] = 0;
    min_val[rt] = a[max_top[rt] + 1] - max_val[rt];
    return ;
  }
  int mid = (l + r) >> 1;
  Build_Tree(lson[rt],l,mid);
  Build_Tree(rson[rt],mid + 1,r);
  push_up(rt);
}

void Update(int rt,int L,int R,int l,int r,int val){
   if(l <= L && r >= R && min_val[rt] > val){
       max_val[rt] += val * max_top[rt];
       min_val[rt] -= val;
       laze[rt] += val; return ;
   }
   if(L == R){
     max_val[rt] += val * max_top[rt];
    // printf("%d max_val =%d
",L,max_val[rt]);
     while(max_top[rt] + 1 <= m && a[max_top[rt] + 1] <= max_val[rt]) max_top[rt] += 1;
     min_val[rt] = (a[max_top[rt] + 1] - max_val[rt]) / max_top[rt];
     if((a[max_top[rt] + 1] - max_val[rt]) % max_top[rt]) min_val[rt] ++;
     return ;
   }
   push_down(rt);
   int mid = (L + R) >> 1;
   if(l <= mid) Update(lson[rt],L,mid,l,r,val);
   if(r > mid) Update(rson[rt],mid + 1,R,l,r,val);
   push_up(rt);
}

int query(int rt,int L,int R,int l,int r){
    if(R < L) return 0;
    if(l <= L && r >= R) return max_val[rt];
    push_down(rt);
    int mid = (L + R) >> 1;
    int ans = 0;
    if(l <= mid) ans = max(ans,query(lson[rt],L,mid,l,r));
    if(r > mid) ans = max(ans,query(rson[rt],mid + 1,R,l,r));
    return ans;
}

void init(){
    tot = 0;
}
int main(){
    int T = read(); int cont = 1;
    while(T --){

        n = read(); m = read(); int q = read();
        init();a[1] = 0;
        for(int i = 2; i <= m; i ++) a[i] = read();
        a[m + 1] = 1<<30;
        Build_Tree(root,1,n);
        printf("Case %d:
",cont ++);
        while(q --){
            char str[5]; scanf("%s",str);
            int l = read(),r = read();
            if(str[0] == 'W'){
               int x = read();
               Update(root,1,n,l,r,x);
            } else if(str[0] == 'Q'){
               int sum = query(root,1,n,l,r);
               printf("%d
",sum);
            }
        }
        printf("
");
    }
}

  

///链接:http://poj.org/problem?id=3321/*题意 对一个序列执行查询和修改三种操作,其中修改比较奇特; 题解:这个如果暴力执行修改操作,那么一定会超时,所以我们考虑引入第二小的值,从而达到目的。减少复杂度 */#include <iostream>#include <string>#include <cstring>#include <algorithm>#include <cstdio>#include <cctype>#include <queue>#include <stdlib.h>#include <cstdlib>#include <math.h>#include <set>#include"queue"#include <vector>#define inf 107374182#define M 10010001#define ll long long#define PII pair<int,int>usingnamespacestd; inline int read(){ int s = 0, w = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar(); } return s * w; } constint N = 1000010; ll sum[N<<4];int n,m; int max_val[N << 2],seg[N << 2],num[N << 2],tot,root,lson[N << 2],rson[N << 2]; int a[N]; void push_up(int rt){ sum[rt] = sum[lson[rt]] + sum[rson[rt]]; max_val[rt] = max(max_val[lson[rt]],max_val[rson[rt]]); if(max_val[lson[rt]] == max_val[rson[rt]]){ num[rt] = num[lson[rt]] + num[rson[rt]]; seg[rt] = max(seg[lson[rt]],seg[rson[rt]]); return ; } if(max_val[rt] == max_val[lson[rt]]){ num[rt] = num[lson[rt]]; seg[rt] = max(seg[lson[rt]],max_val[rson[rt]]); return ; } num[rt] = num[rson[rt]]; seg[rt] = max(seg[rson[rt]],max_val[lson[rt]]); return ; } void Tag_dwon(int rt,int maxx){ if(max_val[rt] <= maxx) return ; sum[rt] = sum[rt] - (ll)num[rt] * (max_val[rt] - maxx); max_val[rt] = maxx; } void push_down(int rt){ Tag_dwon(lson[rt],max_val[rt]); Tag_dwon(rson[rt],max_val[rt]); } void Build_Tree(int &rt,int l,int r){ rt = ++ tot; max_val[rt] = seg[rt] = -1; num[rt] = sum[rt] = 0; if(l == r) { num[rt] = 1; sum[rt] = a[l]; max_val[rt] = a[l]; return ; } int mid = (l + r) >> 1; Build_Tree(lson[rt],l,mid); Build_Tree(rson[rt],mid + 1,r); push_up(rt); } void Update(int rt,int L,int R,int l,int r,int val){ if(L > R) return ; if(max_val[rt] <= val) return ; if(l <= L && r >= R && val > seg[rt]){ sum[rt] = sum[rt] - (ll)num[rt] * (max_val[rt] - val); max_val[rt] = val; return ; } push_down(rt); int mid = (L + R) >> 1; if(l <= mid) Update(lson[rt],L,mid,l,r,val); if(r > mid) Update(rson[rt],mid + 1,R,l,r,val); push_up(rt); } int get_maxx(int rt,int L,int R,int l,int r){ if(L > R) return0; if(l <= L && r >= R) { return max_val[rt]; } push_down(rt); int mid = (L + R) >> 1; int maxx = 0; if(l <= mid) maxx = max(maxx,get_maxx(lson[rt],L,mid,l,r)); if(r> mid) maxx = max(maxx,get_maxx(rson[rt],mid + 1,R,l,r)); return maxx; } ll get_sum(int rt,int L,int R,int l,int r){ if(L > R) return0; if(l <= L && r >= R) { return sum[rt]; } push_down(rt); int mid = (L + R) >> 1; ll ans = 0; if(l <= mid) ans += get_sum(lson[rt],L,mid,l,r); if(r > mid) ans += get_sum(rson[rt],mid + 1,R,l,r); return ans; } void init(){ tot = 0; } int main(){ int T = read(); while(T --){ n = read(); m = read(); init(); for(int i = 1; i <= n; i ++) a[i] = read(); Build_Tree(root,1,n); while(m --){ int op = read(),l = read(),r = read(); if(op == 0){ int t = read(); Update(root,1,n,l,r,t); } elseif(op == 1){ printf("%d ",get_maxx(root,1,n,l,r)); } else { printf("%lld ",get_sum(root,1,n,l,r)); } } } }

原文地址:https://www.cnblogs.com/yrz001030/p/13670538.html