题意
一个序列,要求完成两种操作
1.要求从x到y开方
2.求和
思路
这题主要的问题才tle风险。首先的话,开方开到1的话后面开放就不变,不用再开了。
但是不知道为什么明明这样操作了但是还是报了tle
最后发现是输入数组的问题,顺便加了快读函数,做了一些相应的优化
代码
#include<iostream>
#include<cmath>
#include<stack>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define Endl "\n";
typedef long long ll;
const int maxn=1e5+5;
const int mod=1e9+7;
using namespace std;
ll N,M,key,x,y,test;
ll a[maxn],ans[maxn<<2];
inline ll read(){
ll x = 0, f = 1; char ch; ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void PushUp(int rt)
{
ans[rt]=ans[rt<<1]+ans[rt<<1|1];
}
//建树
void Build(int l,int r,int rt)
{
if (l==r)
{
ans[rt]=read();
return;
}
int mid=(l+r)>>1;
Build(l,mid,rt<<1);
Build(mid+1,r,rt<<1|1);
PushUp(rt);
}
ll Query(int L,int R,int l,int r,int rt)
{
if(L>r||R<l)
return 0;
if (L<=l&&r<=R)
return ans[rt];
int mid=(l+r)>>1;
// PushDown(rt,mid-l+1,r-mid);//若更新只有点更新,不需要这句
ll ANS=0;
if (L<=mid) ANS+=Query(L,R,l,mid,rt<<1);
if (R>mid) ANS+=Query(L,R,mid+1,r,rt<<1|1);
return ANS;
}
void modify(int x,int y,int l,int r,int p)
{
if(y<l||x>r)
return ;
if(ans[p]==(r-l+1))
return ;
else if(l==r)
{
ans[p]=sqrt(ans[p]);
return ;
}
int mid=(l+r)>>1;
if(x<=mid) modify(x,y,l,mid,p<<1);
if(y>mid) modify(x,y,mid+1,r,p<<1|1);
PushUp(p);
}
int main()
{
test=1;
while(cin>>N)
{
// for(int i=1;i<=N;i++)
// cin>>a[i];
Build(1,N,1);
M=read();
printf("Case #%d:\n",test++);
// cout<<"Case #"<<test<<":"<<Endl;;
// test++;
while(M--)
{
// cin>>key>>x>>y;
key=read(),x=read(),y=read();
if(x>y) swap(x,y);
if(key)
{
cout<<Query(x,y,1,N,1)<<Endl;
}
else
{
modify(x,y,1,N,1);
}
}
cout<<Endl;
}
return 0;
}