孩子从昨天调了一天了救救孩子吧QAQ
//2023/6/28
//别着急,先通读一遍题目
//别忘了开long long
//写完先看一遍怎么降复杂度
//要么开全局变量要么给定初值
//想想看,有什么情况需要特判
//看看数组开的够不够大
//std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int MAXN=1e5+10;
int num,ans;
struct node{
int l,r;
int mx,md;//md存放最大值在数组中的位置
int mark;
node(){
l=r=-1;
mx=md=0;
mark=0;
}
}ts[4*MAXN];
int a[MAXN];
bool fyw[MAXN];//标记这个位置有无飞鱼丸
void putup(int id)//得到最大值与最大值的坐标
{
int lcid=id*2;
int rcid=lcid+1;
if(ts[lcid].mx>ts[rcid].mx){
ts[id].mx=ts[lcid].mx;
ts[id].md=ts[lcid].md;
}
else{
ts[id].mx=ts[rcid].mx;
ts[id].md=ts[rcid].md;
}
}
void putdown(int id,int len)//下放懒标记,正常模板
{
int lcid=id*2;
int rcid=lcid+1;
if(ts[id].mark==0) return;
ts[lcid].mark+=ts[id].mark;
ts[rcid].mark+=ts[id].mark;
ts[lcid].mx+=ts[id].mark;
ts[rcid].mx+=ts[id].mark;
ts[id].mark=0;
}
void build(int id,int l,int r)//建树,正常模板
{
ts[id].l=l;
ts[id].r=r;
ts[id].mx=0;
if(l==r) {
ts[id].mx=a[l];
ts[id].md=l;
}
else{
int mid=l+(r-l)/2;
int lcid=id*2;
int rcid=lcid+1;
build(lcid,l,mid);
build(rcid,mid+1,r);
putup(id);
}
}
void update(int id,int goal,int val)//操作1的单点修改
{
if(ts[id].l==ts[id].r){
if(ts[id].l==goal) {
ts[id].mx=val-ts[id].mx;
}
return;
}
int mid=(ts[id].l+ts[id].r)/2;
int lcid=id*2;
int rcid=lcid+1;
if(goal<=mid) update(lcid,goal,val);
if(goal>mid) update(rcid,goal,val);
putup(id);
return;
}
void zero(int id,int goal)//将2中的目标归零
{
if(ts[id].l==ts[id].r){
if(ts[id].l==goal){
num=ts[id].mx;//得到当前位置的能量
ts[id].mx=0;
}
return;
}
int mid=(ts[id].l+ts[id].r)/2;
int lcid=id*2;
int rcid=lcid+1;
if(goal<=mid) zero(lcid,goal);
if(goal>mid) zero(rcid,goal);
putup(id);
}
void lineup(int id,int l,int r,int val)//操作3,区间修改正常模板
{
if(ts[id].l>=l&&ts[id].r<=r){
ts[id].mark+=val;
ts[id].mx+=val;
return;
}
putdown(id,ts[id].r-ts[id].l+1);
int mid=(ts[id].l+ts[id].r)/2;
int lcid=id*2;
int rcid=lcid+1;
if(l<=mid) lineup(lcid,l,r,val);
if(r>mid) lineup(rcid,l,r,val);
putup(id);
}
int show(int id,int l,int r)//找所示区间的最值
{
int mid=(ts[id].l+ts[id].r)/2;
int lcid=id*2;
int rcid=lcid+1;
if(ts[id].l>=l&&ts[id].r<=r)
{
int baka=ts[id].mx;
zero(1,ts[id].md);//将最值归零
return baka;
}
putdown(id,ts[id].r-ts[id].l+1);
int tot=INT_MIN;
if(l<=mid) tot=max(tot,show(lcid,l,r));
if(r>mid) tot=max(tot,show(rcid,l,r));
return tot;
}
int main()
{
int n,m,opt,x,l,r,v;
std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin>>n>>m;
for (int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
bool flag=0;
for (int i=1;i<=m;i++){
cin>>opt;
if(opt==1){
cin>>x>>v;
update(1,x,v);//标记当前位置的飞鱼丸
fyw[x]=1;
}
else if(opt==2){
cin>>l>>r;
int hentai=0;
for (int i=r;i>=l;i--)//在给定区间查找飞鱼丸
{
if(fyw[i]) {
fyw[i]=0;
zero(1,i);//归零
hentai=num;
flag=1;
break;
}
}
if(!flag) hentai=show(1,l,r);//找不到飞鱼丸那就取区间最值
flag=0;
ans+=hentai;
cout<<hentai<<'\n';
}
else{
cin>>l>>r>>v;
lineup(1,l,r,v);//区间修改一下
}
}
if(ans<10000) cout<<"QAQ"<<'\n';
else if(ans<10000000) cout<<"Sakura"<<'\n';
else cout<<"ice"<<'\n';
return 0;
}