社区讨论
为什么我要开八倍空间才能过 (QAQ)
P3372【模板】线段树 1参与者 8已保存回复 20
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 20 条
- 当前快照
- 1 份
- 快照标识符
- @mi7upjzm
- 此快照首次捕获于
- 2025/11/21 03:55 4 个月前
- 此快照最后确认于
- 2025/11/21 04:04 4 个月前
RT
为毛题解说开4倍就行?
CPP#include<bits/stdc++.h>
using namespace std;
#define fcin(a) a=read()
#define sz(a) (tree[a].right_edge-tree[a].left_edge+1)
#define lint long long
struct node
{
int left_edge;
int right_edge;
lint value,wait_value;
};
int temp,l1,r1,d,n,m;
node tree[800050];//400050 就RE三个点。。。
int read()
{
char temp;
int a,sign=1;
sign=1,a=0,temp=getchar();
while(temp<'0'||temp>'9')
{
if(temp=='-') sign=-1;
temp=getchar();
}
while(temp>='0'&&temp<='9')
{
a=a*10+int(temp-'0');
temp=getchar();
}
return a*sign;
}
inline int ls(int x)
{
return (x<<1);
}
inline int rs(int x)
{
return ((x<<1)+1);
}
void build_tree(int left_,int right_,int pos)
{
// cout<<left_<<" "<<right_<<"="<<pos<<endl;
tree[pos].left_edge=left_;
tree[pos].right_edge=right_;
if(left_==right_)//ÈôΪҶ×ӽڵ㣬¶ÁÈëÖµ
{
fcin(tree[pos].value);
return;
}
else //Èô·ÇÒ¶×ӽڵ㣬µÝ¹é
{
int mid=((left_+right_)>>1);
build_tree(left_,mid,ls(pos));
build_tree(mid+1,right_,rs(pos));
tree[pos].value=tree[ls(pos)].value+tree[rs(pos)].value;
}
}
void pass_wait(int pos)
{
if (tree[pos].wait_value==0) return; //½¡×³ÐÔ£¨ÎÞÁÄ¡£¡£¡££©
else
{
tree[pos].value+=sz(pos)*tree[pos].wait_value; //´¦Àíµ±Ç°nodeµÄÀÁ±ê¼Ç
tree[ls(pos)].wait_value+=tree[pos].wait_value;
tree[rs(pos)].wait_value+=tree[pos].wait_value;
tree[pos].wait_value=0;
}
}
lint section_query(int left_,int right_,int pos)//±£Ö¤l_ÖÁr_Çø¼äÊÇposÇø¼ä×Ó¼¯
{
lint l=tree[pos].left_edge,r=tree[pos].right_edge,mid=((l+r)>>1),ans=0;
if (tree[pos].wait_value!=0)
{
pass_wait(pos); //´«ÀÁ±ê¼Ç
}
if (left_==l&&right_==r) return tree[pos].value;
if (left_>mid) ans+=section_query(left_,right_,rs(pos));//Æ«ÓҲֻ࣬ËÑÓÒ×ÓÊ÷
if (right_<=mid) ans+=section_query(left_,right_,ls(pos));//Æ«×ó²à£¬Ö»ËÑ×ó×ÓÊ÷
if (left_<=mid&&right_>mid)//Á½²à¶¼ËÑ
{
ans+=section_query(left_,mid,ls(pos));
ans+=section_query(mid+1,right_,rs(pos));
}
return ans;
}
void section_change(int left_,int right_,int pos,int delta)
{
// cout<<"-- "<<tree[pos].left_edge<<","<<tree[pos].right_edge<<" "<<left_<<","<<right_<<endl;
lint l=tree[pos].left_edge,r=tree[pos].right_edge,mid=((l+r)>>1);
if (left_==l&&right_==r)
{
tree[pos].wait_value+=delta;
return;
}
tree[pos].value+=delta*(right_-left_+1);
if (left_>mid) section_change(left_,right_,rs(pos),delta);//Æ«ÓҲֻ࣬¸ÄÓÒ×ÓÊ÷
if (right_<=mid) section_change(left_,right_,ls(pos),delta);//Æ«×ó²à£¬Ö»¸Ä×ó×ÓÊ÷
if (left_<=mid&&right_>mid)//Á½²à¶¼¸Ä
{
section_change(left_,mid,ls(pos),delta);
section_change(mid+1,right_,rs(pos),delta);
}
}
inline void input()
{
fcin(n);
fcin(m);
build_tree(1,n,1);
}
int out()
{
cout<<"-------------------\n";
for(int i=1; 1; i++)
{
if(tree[i].value==0) break;
cout<<i<<" "<<"["<<tree[i].left_edge<<","<<tree[i].right_edge<<"] ans= "<<tree[i].value<<" wait= "<<tree[i].wait_value<<endl;
}
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
input();
for(int i=1; i<=m; i++)
{
fcin(temp);
if(temp==1)
{
fcin(l1);
fcin(r1);
fcin(d);
section_change(l1,r1,1,d);
}
if(temp==2)
{
fcin(l1);
fcin(r1);
cout<<section_query(l1,r1,1)<<"\n";
}
// out();
}
return 0;
}
/*
8 10
1 1 1 1 1 1 1 1
1 1 8 1
2 3 6
///
5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4
*/
回复
共 20 条回复,欢迎继续交流。
正在加载回复...