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