HDU - 4027
给定一个长度为 N 的数列,有M个操作,操作分两种
一是让指定区间每个数都开方,二是询问区间的和
由于每个数都在LL范围内,所以实际上每个数开方的次数不会很多
用线段树维护区间和,开方就暴力到根,然后逐个开方
当发现区间全部都是 1的时候就直接return
坑点:
- 所有数都大于 0
- 可能出现 l>r的情况,这时候要 swap(l,r)
- 每个case最后还要加一个换行
#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <string>
#include <complex>
using namespace std;
typedef pair<int,int> Pii;
typedef long long LL;
typedef unsigned long long ULL;
typedef double DBL;
typedef long double LDBL;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define SQR(a) ((a)*(a))
#define PCUT puts("\n----------")
const int maxn=1e5+10;
struct SegmentTree
{
struct node
{
int l,r;
LL val;
} segt[maxn<<2];
void build(int,int,int=1);
void update(int,int,int=1);
LL query(int,int,int=1);
void maintain(int);
} tree;
LL inpt[maxn];
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
int N,M,T=0;
while(~scanf("%d", &N))
{
printf("Case #%d:\n", ++T);
for(int i=1; i<=N; i++) scanf("%lld", &inpt[i]);
tree.build(1,N);
scanf("%d", &M);
for(int i=0,t,l,r; i<M; i++)
{
scanf("%d%d%d", &t, &l, &r);
if(l>r) swap(l,r);
if(!t) tree.update(l,r);
else printf("%lld\n", tree.query(l,r));
}
puts("");
}
return 0;
}
void SegmentTree::build(int nl, int nr, int np)
{
node &now = segt[np];
now.l=nl, now.r=nr;
if(nl==nr) {now.val = inpt[nl]; return;}
int mid = (nl+nr)>>1;
build(nl,mid,np*2);
build(mid+1,nr,np*2+1);
maintain(np);
}
void SegmentTree::update(int ql, int qr, int np)
{
node &now = segt[np];
if(now.val==now.r-now.l+1) return;
if(now.l==now.r){now.val=sqrt(now.val); return;}
int mid=(now.l+now.r)>>1;
if(ql<=mid) update(ql,qr,np*2);
if(qr>mid) update(ql,qr,np*2+1);
maintain(np);
}
LL SegmentTree::query(int ql, int qr, int np)
{
node &now = segt[np];
if(ql<=now.l && now.r<=qr) return now.val;
LL ans = 0;
int mid = (now.l+now.r)>>1;
if(ql<=mid) ans += query(ql,qr,np*2);
if(qr>mid) ans += query(ql,qr,np*2+1);
return ans;
}
void SegmentTree::maintain(int np)
{
node &now = segt[np];
if(now.l != now.r)
{
node &lson=segt[np*2], &rson=segt[np*2+1];
now.val = lson.val + rson.val;
}
}