hdu 4027 Can you answer these queries? 线段树+sqrt的特性暴力修改

又傻逼又毒瘤

我还卡了这么久

说明我也又傻逼又毒瘤

#注意每个case后面要有一行空格;

#注意sum会爆int,所以无论是数组还是函数还是输出时,都要开longlong

#为什么可以直接暴力修改?sqrt是个神奇操作,无论多大的数,在很有限的次数里都会开到1,总的修改次数不会很多

#判断该区间是否已经全都不用改了的条件是sum==r-l+1,说明都是1了

#建树的时候可以边建边读入,肯定是合法的

--

#include <iostream>
#include <math.h>
#include <string.h>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <algorithm>
#include <cstdio>
using namespace std;
long long sum[500000];
void build(int rt,int l,int r)
{
    if(l==r)
    {   scanf("%lld",&sum[rt]);
        return;
    }
    if(l<r)
    {
        int mid=(l+r)>>1;
        build(rt<<1,l,mid);
        build(rt*2+1,mid+1,r);
        sum[rt]=sum[rt<<1]+sum[rt*2+1];
    }
}
void update(int rt,int ul,int ur,int l,int r)
{
    if(sum[rt]==r-l+1)
    {
        return;
    }
    if(l==r)
    {
        sum[rt]=(long long)sqrt(double(sum[rt]));
        return;
    }
    int mid=(l+r)>>1;
    if(ul<=mid)
    {
        update(rt<<1,ul,ur,l,mid);
    }
    if(ur>mid)
    {
        update(rt*2+1,ul,ur,mid+1,r);
    }
    sum[rt]=sum[rt<<1]+sum[rt*2+1];
}
long long  query(int rt,int ql,int qr,int l,int r)
{
    
   if(l>=ql&&r<=qr)
   {
       return sum[rt];
   }
   int mid=(l+r)>>1;
   long long ans=0;
   if(ql<=mid)
   {
       ans+=query(rt<<1,ql,qr,l,mid);
   }
   if(qr>mid)
   {
       ans+=query(rt*2+1,ql,qr,mid+1,r);
   }
   return ans;
}
int main( )
{
  int t,m,cnt=0;
  
  //freopen("lys.in","r",stdin);
  
  while(cin>>t)
  { cnt++;
    printf("Case #%d:\n",cnt);
    
      memset(sum,0,sizeof(sum));
      
      build(1,1,t);
      
    cin>>m;
    for(int j=1;j<=m;j++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        
        if(b>c) swap(b,c);
        
        if(a==0)
        {
            update(1,b,c,1,t);
        }
        else {
            printf("%lld\n",query(1,b,c,1,t));
        }
    }
    printf("\n");
  }
}

 

posted @ 2021-10-28 18:04  liyishui  阅读(36)  评论(0编辑  收藏  举报