线段树基础单点更新,区间查找HDU1166,POJ3264,DUT1094等差区间,HDU1754

DUT 1094等差区间 http://dutacm.club:7217/codesheaven/problem.php?id=1094
不涉及更新,但涉及到了数学思想。
1.首先,节点的信息记录区间和,区间平方和,区间最小值
2.通过线段树查找后,假设这段区间为等差区间,根据得到的以上三个信息能够求出等差值d
3.sum=(a1+an)*n/2;求出d
4.根据d,区间长度和最小值,求出该区间的平方和。
5.比较实际平方和与假设平方和是否相等,相等则输出Yes

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
/******************************************************/
#define LL long long int
#define mem(a,b) memset(a,b,sizeof(a))
#define m ((l+r)/2)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define L rt<<1
#define R rt<<1|1
#define N 200000+1
#define pow(a) a*a
#define INF 0x3f3f3f3f
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
/*********************************************************/

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
/******************************************************/
#define LL long long int
#define mem(a,b) memset(a,b,sizeof(a))
#define m ((l+r)/2)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define L rt<<1
#define R rt<<1|1
#define N 100000+1
#define pow(a) a*a
#define INF 0x3f3f3f3f
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
/*********************************************************/
/*5 5
3 1 5 2 4
1 3
4 5
1 4
3 4
2 2*/
int n, q;
struct node{
    LL minn;
    LL sum;
    LL sqr;
};
node tree[N << 2];
void pushup(int rt){
    tree[rt].sum = tree[L].sum + tree[R].sum;
    tree[rt].sqr = tree[L].sqr + tree[R].sqr;
    tree[rt].minn = min(tree[L].minn, tree[R].minn);
}
void build(int l, int r, int rt){
    if (l == r){
        scanf("%lld", &tree[rt].minn);
        tree[rt].sum = tree[rt].minn;
        tree[rt].sqr = pow(tree[rt].sum);
        return;
    }
    build(lson);
    build(rson);
    pushup(rt);
}
node query(int a, int b, int l, int r, int rt){
    node temp;
    if (a <= l&&r <= b){
        temp.minn = tree[rt].minn;
        temp.sum = tree[rt].sum;
        temp.sqr = tree[rt].sqr;
        return temp;
    }
    LL sum = 0, sqr = 0, res = INF;
    if (a <= m){
        temp = query(a, b, lson);
        sum += temp.sum;
        sqr += temp.sqr;
        res = min(res, temp.minn);
    }
    if (b > m){
        temp = query(a, b, rson);
        sum += temp.sum;
        sqr += temp.sqr;
        res = min(res, temp.minn);
    }
    temp.sum = sum;
    temp.sqr = sqr;
    temp.minn = res;
    return temp;
}
int main(){
    while (~scanf("%lld%lld", &n, &q)){
        build(1, n, 1);
        while (q--){
            int a, b;
            scanf("%d%d", &a, &b);
            if (a == b){ printf("Yes\n"); continue; }
            LL len = (b - a + 1);
            node temp = query(a, b, 1, n, 1);
            LL d = ((temp.sum * 2) / len - 2 * temp.minn) / (len - 1);

            LL sqr = len*pow(temp.minn) + pow(d)*(len - 1)*(len * 2 - 1)*len / 6 + temp.minn*d*(len - 1)*len;
            if (sqr == temp.sqr)printf("Yes\n");
            else printf("No\n");
        }
    }
}

HDU1166单节点更新

int sum[N << 2];
void pushup(int rt){
    sum[rt] = sum[L] + sum[R];
}
void build(int l, int r, int rt){
    if (l == r){
        scanf("%d", &sum[rt]);
        return;
    }
    int m = (l + r) / 2;
    build(lson);
    build(rson);
    pushup(rt);
}
int query(int a, int b, int l, int r, int rt){
    if (a <= l&&b >= r){
        return sum[rt];
    }
    int m = (l + r) / 2;
    int res = 0;
    if (a <= m)res += query(a, b, lson);
    if (b > m)res += query(a, b, rson);
    return res;
}
void Add(int k, int c, int l, int r, int rt){
    if (k == l&&k == r){
        sum[rt] += c;
        return;
    }
    int m = (l + r) / 2;
    if (k > m)Add(k, c, rson);
    if (k <= m)Add(k, c, lson);
    pushup(rt);
}
int main(){
    int t;
    cin >> t;
    int cnt = 1;
    while (t--){
        printf("Case %d:\n", cnt++);
        int n;
        scanf("%d", &n);
        build(1, n, 1);
        char s[7];
        while (~scanf("%s", s)){
            if (s[0] == 'E')break;

            if (s[0] == 'Q'){
                int a, b; scanf("%d%d", &a, &b);
                printf("%d\n", query(a, b, 1, n, 1));
            }
            else if (s[0] == 'A'){
                int a, b;
                scanf("%d%d", &a, &b);
                Add(a, b, 1, n, 1);
            }
            else{
                int a, b;
                scanf("%d%d", &a, &b);
                Add(a, -b, 1, n, 1);
            }
        }
    }
}

POJ3264求最大最小值

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<functional>
#include<string>
#include<iostream>
#include<time.h>
/***********************/
using namespace std;
#define N 300000+3
#define NN 40000+10
#define INF 0x3f3f3f3f
#define mem(arr,num) memset(arr,num,sizeof(arr))
#define LL long long int
#define PI acos(-1)
#define mod 1e9+7


int dat[N];
int n, num;
int MAX, MIN;
struct node{

    int max, min;
    int left, right;
    int mid(){
        return (left + right) / 2;
    }
};
node tree[N];
void init(int n_){
    n = 1;
    while (n < n_)n *= 2;
}
void build(int root, int left, int right){
    int mid = (right + left) / 2;
    tree[root].left = left;
    tree[root].right = right;
    if (left + 1 == right){
        tree[root].max = tree[root].min = dat[left];
    }
    else{
        build(root * 2 + 1, left, mid);
        build(root * 2 + 2, mid, right);
        tree[root].max = max(tree[root * 2 + 1].max, tree[root * 2 + 2].max);
        tree[root].min = min(tree[root * 2 + 1].min, tree[root * 2 + 2].min);
    }
}
void query(int left, int right, int root){
    int mid = tree[root].mid();
    if (tree[root].left == left&&tree[root].right == right){
        MAX = max(tree[root].max, MAX);
        MIN = min(tree[root].min, MIN);
        return;
    }
    if (left >= mid){
        query(left, right, root * 2 + 2);
    }
    else if (right <= mid){
        query(left, right, root * 2 + 1);
    }
    else{
        query(left, mid, root * 2 + 1);
        query(mid, right, root * 2 + 2);
    }

}
int main(){




    while (~scanf("%d", &n))
    {
        int k; scanf("%d", &k);
        num = n;
        init(n);
        for (int i = 0; i < num; i++)scanf("%d", &dat[i]);
        build(0, 0, num);

        while (k--){
            int a, b;

            scanf("%d%d", &a, &b);
            MAX = -INF;
            MIN = INF;
            query(a - 1, b, 0);


            printf("%d\n", MAX - MIN);

        }

    }


}

HDU1754单点更新

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
/******************************************************/
#define LL long long int
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define L rt<<1
#define R rt<<1|1
#define N 200000+1
#define pow(a) a*a
#define INF 0x3f3f3f3f
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
/*********************************************************/
/*5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5*/
int m, n;
int sum[N << 2];
int father[N];
void find(int rt){
    sum[rt] = max(sum[L], sum[R]);
}
void build(int l, int r, int rt){
    if (l == r){
        scanf("%d", &sum[rt]);
        father[l] = rt;
        return;
    }
    int m = (l + r) / 2;
    build(lson);
    build(rson);
    find(rt);
}
int query(int a, int b, int l, int r, int rt){
    if (a <= l&&r <= b){
        return sum[rt];
    }
    int m = (l + r) / 2;
    int res = 0, res2 = 0;
    if (a <= m)res = query(a, b, lson);
    if (b > m)res2 = query(a, b, rson);
    return max(res, res2);
}
void update(int k, int a, int l, int r, int rt){
    int node = father[k];
    sum[node] = a;
    while (node > 1){
        node = (node >> 1);
        find(node);
    }
}
/*上下都可以*/
/*void update(int k, int a, int l, int r, int rt){
    if (k == l&&k == r){
        sum[rt] = a;
        return;
    }
    int m = (l + r) / 2;
    if (k <= m)update(k, a, lson);
    if (k > m)update(k, a, rson);
    find(rt);
}*/
int main(){
    while (~scanf("%d%d", &n, &m)){
        mem(sum, 0);
        mem(father, 0);
        build(1, n, 1);
        sum[0];
        while (m--){
            char s[2]; int a, b;
            scanf("%s%d%d", s, &a, &b);
            if (s[0] == 'Q'){
                sum[5];
                father[5];
                printf("%d\n", query(a, b, 1, n, 1));
            }
            else{
                update(a, b, 1, n, 1);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值