线段树专题

hdu1166   http://acm.hdu.edu.cn/showproblem.php?pid=1166
#include<cstdio>

#define lson l, m, rt << 1
#define rson m+1, r, rt <<1 | 1

const int maxn = 55555;
int sum[maxn << 2];

void pushup(int rt){
    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}

void build(int l, int r, int rt){
    if (l == r){
        scanf("%d", &sum[rt]);
        return;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(rt);
}

void update(int p, int add, int l, int r, int rt){
    if (l == r){
        sum[rt] += add;
        return;
    }
    int m = (l + r) >> 1;
    if (p <= m) update(p, add, lson);
    else update(p, add, rson);
    pushup(rt);
}

int query(int L, int R, int l, int r, int rt){
    if (L <= l && r <= R) {
        return sum[rt];
    }
    int m = (l + r) >> 1;
    int ret = 0;
    if (L <= m) ret += query(L, R, lson);
    if (R > m) ret += query(L, R, rson);

    return ret;
}

int main(){
    int test, n;
    scanf("%d", &test);
    for (int t = 1; t <= test; t++){
        printf("Case %d:\n", t);

        scanf("%d",&n);
        build(1, n, 1);
        char op[10];
        while(scanf("%s",op)){
            if (op[0] == 'E') break;

            int a,b;
            scanf("%d%d",&a, &b);

            if (op[0] == 'Q')
                printf("%d\n", query(a, b, 1, n, 1));

            else if (op[0] == 'S')
                update(a, -b, 1, n, 1);

            else update(a, b, 1, n, 1);
        }
    }
    return 0;
}

hdu1754  http://acm.hdu.edu.cn/showproblem.php?pid=1754

#include<cstdio>
#include<algorithm>
#include<cstring>
#define lson l, m, rt << 1
#define rson m+1, r, rt <<1 | 1

const int maxm = 222222;
int sum[maxm << 2];

void pushup(int rt){
    sum[rt] = std::max(sum[rt << 1], sum[rt << 1 | 1]);
}

void build(int l, int r, int rt){
    if (l == r) {
        scanf("%d",&sum[rt]);
        return ;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(rt);
}

void updata(int p, int prc, int l, int r, int rt){
    if (l == r){
        sum[rt] = prc;
        return;
    }
    int m = (l + r) >> 1;
    if (p <= m) updata(p, prc, lson);
    if (p > m) updata(p, prc, rson);
    pushup(rt);
}

int query(int L, int R, int l, int r, int rt){
    if (L <= l && r <= R){
        return sum[rt];
    }
    int m = (l + r) >> 1;
    int maxn = 0;
    if (L <= m) maxn = std::max(maxn, query(L, R, lson));
    if (R > m) maxn = std::max(maxn, query(L, R, rson));
    return maxn;
}
int main(){
    int n, m;
    while(~scanf("%d%d", &n, &m)){
        memset(sum, 0, sizeof(sum));
        build(1, n, 1);
        while(m--){
            char c[2];
            int a, b;
            scanf("%s%d%d", c, &a, &b);
            if (c[0] == 'Q')
                printf("%d\n",query(a, b, 1, n, 1));
            else updata(a, b, 1, n, 1);
        }
    }
}

hdu2795 http://acm.hdu.edu.cn/showproblem.php?pid=2795

因为本身建树会达到4*10^9,明显不行,考虑到海报数量,即使不覆盖的贴,也就200000个,即最多2000000个叶子。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define lson l, m, rt << 1
#define rson m+1, r, rt <<1 | 1

const int maxm = 200005;
int sum[maxm << 2];
int h,n,w,p,post;

void pushup(int rt){
    sum[rt] = std::max(sum[rt << 1], sum[rt << 1|1]);
}

void build(int l, int r, int rt){
    if (l == r){
        sum[rt] = w;
        return ;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(rt);
}

void updata(int p, int l, int r, int rt){
    if (l == r){
        if (sum[rt] >= p) {
            sum[rt] -= p;
            post = l;
        }else post = -1;
        return ;
    }
    if (sum[rt] < p) {
        post = -1;
        return ;
    }
    int m = (l + r) >> 1;
    if (sum[rt << 1] >= p) updata(p, lson);
    else updata(p, rson);

    pushup(rt);
}
int main(){
    while(std::cin >> h >> w >> n){
        memset(sum, 0, sizeof(sum));

        int nn = std::min(h, n);
        build(1, nn, 1);

        while(n--){
            std::cin >> p;
            updata(p, 1, nn, 1);
            printf("%d\n", post);
        }
    }
}

poj2886 http://poj.org/problem?id=2886

编完头脑发晕啊,各种细节要注意。。。

#include<iostream>
#include<cstdio>
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1 | 1

using namespace std;

const int maxn = 2222222;
int sum[maxn << 2];
int pos;

struct aaa{
    char name[15];
    int val;
}a[maxn];

const int antiprime[]={1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,5040,7560,10080,15120,20160,25200,27720,45360,50400,55440,83160,110880,166320,221760,277200,
 332640,498960,554400,665280};
 /// 反素数表, 反素数指1-n中含有素因子数最多的数

const int factorNum[]={1,2,3,4,6,8,9,10,12,16,18,20,24,30,32,36,40,48,60,64,72,80,84,
 90,96,100,108,120,128,144,160,168,180,192,200,216,224};
/// 反素数对应的约数个数

void pushup(int rt){
    sum[rt] = sum[rt<< 1] + sum[rt << 1 | 1];
}

void build(int l, int r, int rt){
    if (l == r){
        sum[rt] = 1;
        return ;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(rt);
}

void updata(int k, int l, int r, int rt){
    if (l == r){
        sum[rt] = 0;
        pos = l;
        return ;
    }
    int m = (l + r) >> 1;
    if (k <= sum[rt << 1]) updata(k, lson);
    else updata(k-sum[rt << 1], rson);
    pushup(rt);
}

int main(){

    int n, k;
    while(cin >> n >> k){
        for (int i = 0; i < n; i++){
            scanf("%s%d",&a[i+1].name, &a[i+1].val);
        }
        build(1, n, 1);

        int cnt = 0;
        while (cnt < 35 && antiprime[cnt] <= n) cnt++;
        cnt--;
        updata(k,1,n,1);
        for (int i = 1; i < antiprime[cnt]; i++){

            int mod = sum[1];

            if (a[pos].val > 0) {
                k = (k + a[pos].val - 1) % mod;
                if ( k == 0 ) k = mod;

            }else{
                k = (k + a[pos].val) % mod;
                if (k <= 0) k += mod;
            }
            updata(k, 1, n, 1);

        }
        printf("%s %d\n",a[pos].name, factorNum[cnt]);
    }

}


hdoj1698 http://acm.hdu.edu.cn/showproblem.php?pid=1698

#include<iostream>
#include<cstdio>
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1 | 1

using namespace std;

const int maxn = 2222222;
int sum[maxn << 2];
int flag[maxn << 2];

void down(int rt, int l, int r){
    if (flag[rt]){
        flag[rt << 1] = flag[rt << 1 |1] = flag[rt];
        int m = (l + r) >> 1;
        sum[rt << 1] = (m - l + 1) *flag[rt];
        sum[rt << 1|1] = (r - m)*flag[rt];
        flag[rt] = 0;
    }
}

void pushup(int rt){
    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}

void build(int l, int r, int rt){

    flag[rt] = 0;
    if (l == r){
        sum[rt] = 1;
        return ;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(rt);
}

void updata(int x, int y, int z, int l, int r, int rt){
    if (x <= l && r <= y){
        sum[rt] = (r - l + 1) * z;
        flag[rt] = z;
        return ;
    }
    down(rt, l, r);
    int m = (l + r) >> 1;
    if (y <= m) updata(x, y, z ,lson);
    else if (x > m) updata(x, y, z, rson);
    else {
        updata(x, y, z, lson);
        updata(x, y, z, rson);
    }
    pushup(rt);
}

void query(int l, int r){

}
int main(){
    int test, n, x, y, z, op;
    cin >> test;
    for (int t = 0; t < test; t++){
        cin >> n;
        build(1, n, 1);
        cin >> op;
        while(op--){
            cin >> x >> y >> z;
            updata(x, y, z, 1, n, 1);
        }
        cout << "Case " << t+1 << ": The total value of the hook is " <<  sum[1] << "."<< endl;
    }
}

poj3468 http://poj.org/submit?problem_id=3468

#include<iostream>
#include<cstdio>
#include<cstring>
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1 | 1
#define ll long long

using namespace std;

const int maxn = 2222222;
ll sum[maxn << 2];
ll flag[maxn << 2];

void down(int rt, int l, int r){
    if (flag[rt]){
        int m = (l + r) >> 1;
        flag[rt << 1] += flag[rt];
        flag[rt << 1|1] += flag[rt];
        sum[rt << 1] += (m -l + 1)*flag[rt];
        sum[rt << 1|1] += (r-m)*flag[rt];
        flag[rt] = 0;
    }
}

void pushup(int rt){
    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}

void build(int l, int r, int rt){
    flag[rt] = 0;
    if (l == r) {
        cin >> sum[rt];
        return ;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(rt);
    //cout << l << " " << r << " " << sum[rt] << endl;
}

void updata(int a, int b, ll c, int l, int r, int rt){
        if (a <= l && r <= b){
            flag[rt] += c;
            sum[rt] += (r - l + 1) * c;
            return ;
        }

        down(rt, l, r);

        int m = (l + r) >> 1;
        if (b <= m) updata(a, b, c, lson);
        else if (a > m) updata(a, b, c, rson);
        else{
            updata(a, m, c, lson);
            updata(m+1, b, c, rson);
        }
        pushup(rt);
}

ll query(int a, int b, int l, int r, int rt){
       // cout << l << " " << r << " " << sum[rt] << endl;
        if (a<= l && r <= b){
            return sum[rt];
        }
        down(rt, l, r);
        int m = (l + r) >> 1;
        ll ans = 0;
        if (b <= m) return query(a, b, lson);
        else if (a > m) return query(a, b, rson);
        else{
            ans += query(a, m, lson);
            ans += query(m+1, b, rson);
            return ans;
        }

}

int main(){
        int n, q, a, b;
        ll c;
        cin >> n >> q;
        build(1, n, 1);
        while(q--){
            char ch;
            cin >> ch;
            if (ch == 'Q'){
                cin >> a >> b;
                cout << query(a, b, 1, n, 1) << endl;
            }else{
                cin >> a >> b >> c;
                updata(a, b, c, 1, n, 1);
            }
        }
}

poj2528

#include<iostream>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <cmath>
#include <algorithm>
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1|1

using namespace std;
const int maxn = 20002;
int sum[maxn << 2];
int dd[maxn << 2];
int d[maxn << 2];
bool v[maxn << 2];
struct aaa{
     int l;
     int r;
}a[maxn << 2];

int ans, e;
void pushup(int rt){
     sum[rt] = sum[rt<< 1] && sum[rt << 1|1]; 
}

void build(int l, int r, int rt){
     if (l == r){
           sum[l] = 0;
           return ;
     }
     int m = (l + r) >> 1;
     build(lson);
     build(rson);
     pushup(rt);
}

void updata(int tl, int tr, int l, int r, int rt, int pos){
     if (sum[rt]) return ;
     if ( tl <= l && r <= tr){
          sum[rt] = 1;
          if (!v[pos]){
             ans++;
             v[pos] = true;
          }
          return ;
     }
     
     int m = (l + r) >> 1;
     if (tl <= m) updata(tl, tr, lson, pos);
     if (m < tr) updata(tl, tr, rson, pos);
     pushup(rt);
}

int get(int x){
    int l = 1; int r = e; 
    while(l <= r){
        int m = ( l + r ) >> 1;
        if (d[m] == x) return m;
        if (d[m] > x) r = m-1;
        else l = m + 1;
    }
}

int main(){
    int ase, n;
    cin >> ase;
    while(ase--)
    {
        memset(v,0,sizeof(v));
        ans = 0;
        cin >> n;
        int ep = 0;
        for (int i = 0; i < n; i++)
        {
            cin >> a[i].l >> a[i].r;
            dd[++ep] = a[i].l;
            dd[++ep] = a[i].r;
        }
        sort(dd+1, dd+ ep + 1);
        e = 1;
        d[1] = dd[1];
        
        for (int i = 2; i <= ep; i++)
        {
            if (dd[i] != d[e]) d[++e] = dd[i];
        }
        
        for (int i = e; i >1; i--)
        {
            if (d[i] > d[i-1]+1) d[++e] = d[i-1] + 1;
        }
        
        sort(d+1, d+e+1);
        
        build(1, n, e);
        //cout << "*****************";
        for (int i = 0; i < n; i++){
            int l = get(a[i].l);
            int r = get(a[i].r);
            updata(d[l], d[r], 1, e, 1, i);
        }
        cout << ans << endl;
        }
}
        
                                  

hdoj3308

#include<iostream>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <cmath>
#include <algorithm>
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1|1

using namespace std;
const int maxn = 100005;
int a[maxn];

struct aaa{
    int l;
    int r;
    int m;
}tree[maxn << 2];

void pushup(int rt, int l, int r){
    int ll = rt << 1;
    int rr = rt << 1|1;
    tree[rt].l = tree[ll].l;
    tree[rt].r = tree[rr].r;
    tree[rt].m = max(tree[ll].m, tree[rr].m);
    int m = (l +r) >> 1;
    if (a[m] < a[m+1]){
        if (tree[ll].l == m - l + 1) tree[rt].l += tree[rr].l;
        if (tree[rr].r == r-m) tree[rt].r += tree[ll].r;
        int t = tree[ll].r + tree[rr].l;
        if (t > tree[rt].m) tree[rt].m = t;
    }
}

void build(int l, int r, int rt){
    if (l == r){
        tree[rt].l = tree[rt].m = tree[rt].r = 1;
        cin >> a[l];
        return ;
    }

    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    pushup(rt, l, r);
}

void updata(int x, int y, int l, int r, int rt){
    if (l == r){
        a[l] = y;
        return ;
    }
    int m = (l + r) >> 1;
    if (x <= m) updata(x,y,lson);
    else updata(x,y,rson);
    pushup(rt,l,r);
}

int query(int ll, int rr, int l, int r, int rt){
    if (ll <= l && r <= rr){
        return tree[rt].m;
    }
    int m = (l+r) >> 1;
    int t1 = 0;
    int t2 = 0;
    ///*
    if (ll <= m) t1 = query(ll, rr, lson);
    if (rr > m) t2 = query(ll, rr, rson);
    int t = max(t1, t2);
    if (a[m] < a[m+1]){
        t1 = min(tree[rt << 1].r, m-ll+1);
        t2 = min(tree[rt << 1|1].l, rr-m);
        t1+= t2;
        t = max(t1,t);
    }
    return t;
    
    /*
    if (rr <= m) return query(ll,rr,lson);
    else if (ll > m) return query(ll,rr,rson);
    else{
        t1 = query(ll,m,lson);
        t2 = query(m+1,rr,rson);
        int t = max(t1,t2);
        if (a[m] < a[m+1]){
            t1 = min(tree[rt<<1].r, m-ll+1);
            t2 = min(tree[rt<<1|1].l, rr - m);
            t1+=t2;
        }
        return max(t,t1);
    }
    */
}

int main(){
    int t, n, m;
    cin >> t;
    while(t--){
        cin >> n >> m;
        build(1, n, 1);

        while(m--){
            char ch[5];
            int l, r;
            scanf("%s%d%d",ch,&l,&r);
            if (ch[0] == 'Q'){
                cout << query(++l,++r,1,n,1) << endl;
            }else{
                updata(++l,r,1,n,1);
            }
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值