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);
}
}
}
}