HDU

来源:互联网 发布:tcp20端口和21端口 编辑:程序博客网 时间:2024/06/14 09:21

 HDU - 4027  http://acm.hdu.edu.cn/showproblem.php?pid=4027

题意:更新的时候把要求区间内的值都更新为自己开根号,查询时查询区间和。

思路:  感觉自己有个不好的习惯,有题目没思路时老是容易去看题解或是discuss,这个习惯真的要改一下。

这个题由于是根号,所以必须得更新到点,然后会发现,每次开根号一个数会很快变成1,这时再对这段区间开根号是毫无意义的,所以记录下区间和为长度的部分,到这部分就不用更新了。(如果这里不加以考虑会tle)

然后就是sqrt的问题,这个函数是这样的  double sqrt(double n),所以如果用long long型塞进去会有问题,最好是改成n*1.0。


/*区间更新(这个区间更新还是需要更新到点的,但是需要优化)区间查询*/#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define ll long longconst int maxn = 1e5+10;ll d[maxn],v[maxn<<2];int n;void build(int l,int r,int id){    v[id] = 0;    if(l == r) {v[id] = d[l]; return;}    int m = l+r>>1;    build(l,m,id<<1);    build(m+1,r,id<<1|1);    v[id] = v[id<<1] + v[id<<1|1];}void up(int ul,int ur,int id,int l,int r){    if(l > ur || r < ul) return;    if(v[id] == r-l+1) return;    if(l == r) {v[id] = sqrt(v[id]*1.0); return;}    int m = l+r>>1;    if(ul <= m) up(ul,ur,id<<1,l,m);    if(ur >  m) up(ul,ur,id<<1|1,m+1,r);    v[id] = v[id<<1] + v[id<<1|1];}ll qu(int ql,int qr, int id, int l, int r){    if(l > qr || r < ql) return 0;    if(l >= ql && r <= qr) return v[id];    int m = l+r>>1;    ll ans = 0;    if(ql <= m) ans += qu(ql,qr,id<<1,l,m);    if(qr >  m) ans += qu(ql,qr,id<<1|1,m+1,r);    return ans;}int main(){    int q,a,b,c,kase = 1;    while(~scanf("%d",&n))    {        for(int i = 1; i <= n; i++)            scanf("%I64d",&d[i]);        build(1,n,1);        scanf("%d",&q);        printf("Case #%d:\n",kase++);        while(q--)        {            scanf("%d%d%d",&a,&b,&c);            if(b > c) swap(b,c);            if(!a)  up(b,c,1,1,n);            else printf("%I64d\n",qu(b,c,1,1,n) );        }        printf("\n");    }    return 0;}




原创粉丝点击