暑假集训之后写的第一篇博客。。
开学以来一直在准备网络赛,前几场比赛的还可以,再有10天就现场赛了,感觉时间过的好快,好像还有好多的东西都没接触
呢。  哎,学校条件不够优越,马上要比赛了还要天天上课。  今年尽力吧,争取拿个银奖!!
本题线段树,好长时间都没写过线段树题了,暑假时写过一道,那时写了几个小时没写出来, 之后再碰见线段树题都有点胆怯了,这几天有时间的话再把那题重做一遍。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027
题目大意:给一个长度为n的序列s,有m次询问,每次询问给出三个数,a,b,c,
如果a==1,即输出s[b]+s[b+1]+...+s[c]的和。
如果a==0,即把s[b],s[b+1],...s[c]每个数开方取整!
思路:由于数据量很大,很明显要用到线段树,由于序列中的每个数最大为2^64,经过7,8次开方就变成1了,之后再对1开方就不变了!建立线段树之后 每个叶子节点最多只需要访问8次, 可以给每个节点加一个域,用来判断该节点包含的所有数
是否都已经为1,之后就很容易了!
code:
# include
# include
# include
//using namespace std;
# define N 100005
struct node{
    int cp;
    int l,r;
    __int64 sum;
}tree[8*N];
__int64 a[N],Max;
void bulid(int l,int r,int t)
{
    int mid;
    tree[t].l=l;
    tree[t].r=r;
    tree[t].cp=0;
    if(l==r) {
        tree[t].sum=a[r];
        if(a[r]==1) tree[t].cp=1;
        return;
    }
    mid=(l+r)/2;
    bulid(l,mid,2*t);
    bulid(mid+1,r,2*t+1);
    tree[t].sum=tree[2*t].sum+tree[2*t+1].sum;
    if(tree[2*t].cp==1 && tree[2*t+1].cp==1) tree[t].cp=1;
}
void updata(int l,int r,int t)
{
    __int64 ans;
    if(tree[t].cp==1) return;
    if(tree[t].l==tree[t].r)
    {
        ans=tree[t].sum;
        ans=(__int64)sqrt((double)ans);
        if(ans==1) tree[t].cp=1;
        tree[t].sum=ans;
        return; 
    }
    if(r<=tree[2*t].r) updata(l,r,2*t);
    else if(l>=tree[2*t+1].l) updata(l,r,2*t+1);
    else 
    {
        updata(l,tree[2*t].r,2*t);
        updata(tree[2*t+1].l,r,2*t+1);
    }
    tree[t].sum=tree[2*t].sum+tree[2*t+1].sum;
    if(tree[2*t].cp==1 && tree[2*t+1].cp==1) tree[t].cp=1;
}
void query(int l,int r,int t)
{
    if(tree[t].l==l && tree[t].r==r)
    {
        if(tree[t].cp==1) {Max+=tree[t].sum;return;}
        else if(tree[t].l==tree[t].r) {Max+=tree[t].sum;return;}
    }
    if(r<=tree[2*t].r) query(l,r,2*t);
    else if(l>=tree[2*t+1].l) query(l,r,2*t+1);
    else
    {
        query(l,tree[2*t].r,2*t);
        query(tree[2*t+1].l,r,2*t+1);
    }
}
int main()
{
    int i,n,Q,ch,from,to,ncase=0,tmp;
    while(scanf("%d",&n)!=EOF)
    {
        ncase++;
        for(i=1;i<=n;i++)
            scanf("%I64d",&a[i]);
        bulid(1,n,1);
        scanf("%d",&Q);
        printf("Case #%d:\n",ncase);
        while(Q--)
        {
            scanf("%d%d%d",&ch,&from,&to);
            if(from>to) {tmp=from;from=to;to=tmp;}
            if(ch==0) updata(from,to,1);
            else 
            {
                Max=0;
                query(from,to,1);
                printf("%I64d\n",Max);
            }
        }
        printf("\n");
    }
    return 0;
}
   
 
                    
                 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号