hdu 1698
一个语句顺序错了,我弄了2个小时才找到(细心才是王道)
这个题是线段树区间更新,区间查询
#include<stdio.h>
#include<algorithm>
#define maxn 100000*4+10
using namespace std;
struct node
{
int l;
int r;
int value;
int lazy;
} tr[maxn];
int a[maxn];
void pushup(int ro)
{
tr[ro].value=tr[ro<<1].value+tr[ro<<1|1].value;
}
void pushdown(int ro)
{if(tr[ro].lazy > 0){
tr[ro<<1].lazy=tr[ro].lazy;
tr[ro<<1|1].lazy=tr[ro].lazy;
tr[ro<<1].value=tr[ro].lazy*(tr[ro<<1].r-tr[ro<<1].l+1);
tr[ro<<1|1].value=tr[ro].lazy*(tr[ro<<1|1].r-tr[ro<<1|1].l+1);
tr[ro].lazy=0;}
}
void build(int ro,int l,int r)
{
tr[ro].l=l;
tr[ro].r=r;
tr[ro].lazy=0;//就是这,浪费了我2个小时
if(l==r)
{
tr[ro].value=a[l];
return;
}
int mid=(l+r)/2;
build(ro*2,l,mid);
build(ro*2+1,mid+1,r);
pushup(ro);
}
void update(int ro,int ll,int rr,int val)
{
if(rr<tr[ro].l||ll>tr[ro].r)
return ;
if(tr[ro].l>=ll&&tr[ro].r<=rr)
{
tr[ro].lazy=val;
tr[ro].value=val*(tr[ro].r-tr[ro].l+1);
return;
}
pushdown(ro);
int mid=(tr[ro].l+tr[ro].r)/2;
// if(ll<=mid)//可要可不要
update(ro*2,ll,rr,val);
// if(rr>mid)//可要可不要
update(ro*2+1,ll,rr,val);
pushup(ro);
}
int query(int ro,int l,int r)
{
if(l<=tr[ro].l&&r>=tr[ro].r)
return tr[ro].value;
int mid=(tr[ro].l+tr[ro].r)/2;
pushdown(ro);
int res=0;
if(r<=mid) res+=query(ro*2,l,r);
else if(l>mid) res+=query(ro*2+1,l,r);
else res+=query(ro*2,l,r)+query(ro*2+1,l,r);
return res;
}
int main()
{
int i,t1,t2,t3=1,n;
int x,y,z;
scanf("%d",&t1);
while(t1--)
{
scanf("%d",&n);
for(i=1; i<=n; i++)a[i]=1;
build(1,1,n);
scanf("%d",&t2);
while(t2--)
{
scanf("%d%d%d",&x,&y,&z);
update(1,x,y,z);
}
printf("Case %d: The total value of the hook is %d.\n",t3++,query(1,1,n));
}
return 0;
}我参考的代码段:
/*
线段树+修改区间+询问区间
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<map>
#include<math.h>
typedef long long ll;
//typedef __int64 int64;
const int maxn = 100005;
const int maxm = 1005;
const int inf = 0x7FFFFFFF;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std;
#define LEFT( x ) (x<<1)
#define RIGHT( x ) ((x<<1)+1)
struct node{
int l,r,sum;
int flag;
}tree[ maxn<<2 ];
int data[ maxn ];
void pushup( int n ){
tree[ n ].sum = tree[ LEFT( n ) ].sum+tree[ RIGHT( n ) ].sum;
return ;
}
void pushdown( int n,int m ){//下标为n,这段区间有m个数
if( tree[ n ].flag!=0 ){
tree[ LEFT( n ) ].flag = tree[ RIGHT( n ) ].flag = tree[ n ].flag;
tree[ LEFT( n ) ].sum = tree[ n ].flag*(m-m/2);//tree[ n ].flag*((m+1)/2);
tree[ RIGHT( n ) ].sum = tree[ n ].flag*(m/2);//tree[ n ].flag*( m-(m+1)/2 );
tree[ n ].flag = 0;
}
return;
}
void build( int l,int r,int n ){
if( l==r ){
tree[ n ].sum = data[ l ];
tree[ n ].flag = 0;
tree[ n ].l=tree[ n ].r = l;
return ;
}
tree[ n ].flag = 0;
tree[ n ].l = l;
tree[ n ].r = r;
int mid;
mid = (l+r)>>1;
build( l,mid,LEFT( n ) );
build( mid+1,r,RIGHT( n ) );
pushup( n );
return;
}
void update( int a,int b,int c,int l,int r,int n ){
if( a==l&&b==r ){
tree[ n ].flag = c;
tree[ n ].sum = (r-l+1)*c;
return ;
}
pushdown( n,r-l+1 );
//printf("test\n");
int mid;
mid = (l+r)>>1;
if( mid>=b ) update( a,b,c,l,mid,LEFT( n ) );
else if( mid<a ) update( a,b,c,mid+1,r,RIGHT( n ));
else {
update( a,mid,c,l,mid,LEFT( n ) );
update( mid+1,b,c,mid+1,r,RIGHT( n ) );
}
pushup( n );
return ;
}
int query( int a,int b,int l,int r,int n ){
if( a==l&&b==r ){
return tree[ n ].sum;
}
pushdown( n,r-l+1 );
int mid;
mid = (l+r)>>1;
if( mid>=b ) return query( a,b,l,mid,LEFT( n ) );
else if( mid<a ) return query( a,b,mid+1,r,RIGHT( n ));
else return query( a,mid,l,mid,LEFT( n ) )+query( mid+1,b,mid+1,r,RIGHT( n ));
}
int main(){
int ca;
scanf("%d",&ca);
for( int t=1;t<=ca;t++ ){
int n;
scanf("%d",&n);
for( int i=1;i<=n;i++ ){
data[ i ] = 1;
}
build( 1,n,1 );
int op;
scanf("%d",&op);
while( op-- ){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
update( a,b,c,1,n,1 );
}
printf("Case %d: The total value of the hook is %d.\n",t,tree[ 1 ].sum);
}
return 0;
}贴上线段树延迟标记写法:
void pushup(int index){
tree[index].sum = tree[index<<1].sum+tree[index<<1|1].sum;
tree[index].mx = max(tree[index<<1].mx,tree[index<<1|1].mx);
tree[index].mn = min(tree[index<<1].mn,tree[index<<1|1].mn);
}
void pushdown(int index){
//说明该区间之前更新过
//要想更新该区间下面的子区间,就要把上次更新该区间的值向下更新
if(tree[index].add > 0){
//替换原来的值
/*
tree[index<<1].sum = (tree[index<<1].r-tree[index<<1].l+1)*tree[index].add;
tree[index<<1|1].sum = (tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].add;
tree[index<<1].mx = tree[index].add;
tree[index<<1|1].mx = tree[index].add;
tree[index<<1].mn = tree[index].add;
tree[index<<1|1].mn = tree[index].add;
tree[index<<1].add = tree[index].add;
tree[index<<1|1].add = tree[index].add;
tree[index].add = 0;*/
//在原来的值的基础上加上val
tree[index<<1].sum += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].add;
tree[index<<1|1].sum +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].add;
tree[index<<1].mx += tree[index].add;
tree[index<<1|1].mx += tree[index].add;
tree[index<<1].mn += tree[index].add;
tree[index<<1|1].mn += tree[index].add;
tree[index<<1].add += tree[index].add;
tree[index<<1|1].add += tree[index].add;
tree[index].add = 0;
}
}
浙公网安备 33010602011771号