简单线段树,自己还是做了挺久的,,,
改了一个地方过了,,也不太清楚为甚么
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<stack>
#include<cmath>
#include<map>
#include<vector>
#define ll long long
#define inf 0x3f3f3f3f
#define INF 1000000000
#define bug1 cout<<"bug1"<<endl;
#define bug2 cout<<"bug2"<<endl;
#define bug3 cout<<"bug3"<<endl;
using namespace std;
const int maxn=1e5+5;
int sum[maxn*4],a[maxn],lazy[maxn*4];
void up(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r,int rt){
if(l==r){
sum[rt]=a[l];return;
}
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
up(rt);
}
void down(int rt,int l,int r){
lazy[rt<<1|1]=lazy[rt<<1]=lazy[rt];
int mid=(l+r)>>1;
sum[rt<<1]=(mid-l+1)*lazy[rt];
sum[rt<<1|1]=(r-mid)*lazy[rt];//
//sum[rt]=lazy[rt]*(r-l+1);原本是这样写的,,错了,
}
void update(int ql,int qr,int l,int r,int rt,int k){
if(ql<=l&&r<=qr){
lazy[rt]=k;
sum[rt]=(r-l+1)*k;
return;
}
if(lazy[rt])down(rt,l,r);
int mid=(l+r)>>1;
if(ql<=mid)update(ql,qr,l,mid,rt<<1,k);
if(mid<qr)update(ql,qr,mid+1,r,rt<<1|1,k);
up(rt);
}
long long query(int ql,int qr,int l,int r,int rt){
if(ql<=l&&r<=qr){
return sum[rt];
}
if(lazy[rt])down(rt,l,r);
int mid=(l+r)>>1;
long long ret=0;
if(ql<=mid)ret+=query(ql,qr,l,mid,rt<<1);
if(mid<qr)ret+=query(ql,qr,mid+1,r,rt<<1|1);
return ret;
}
int main(){
int t;
scanf("%d",&t);
int _case=1;
while(t--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i)
a[i]=1;
for(int i=1;i<=4*n-1;++i)
lazy[i]=0;
build(1,n,1);
int m;
scanf("%d",&m);
for(int i=1;i<=m;++i){
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
update(l,r,1,n,1,k);
}
printf("Case %d: The total value of the hook is %d.\n",_case++,sum[1]);
}
}
这个地方是对于区间更新。
这个问题的办法是,建立线段树build(1,1,8000),代表区间1~8000, 然后更新时是update(1,1,8000, a+1,b,c);
#include<iostream>
#include<cstdio>
#include<cstring>
#define mem(str,x) memset(str,(x),sizeof(str))
#define FOR(i,s,t) for(int i=(s); i<(t); ++i)
#define FF(i,n) for(int i=0; i<(n); ++i)
#define mid ((ql+qr)>>1)
#define len (qr-ql+1)
#define lson rt<<1, ql, m
#define rson rt<<1|1, m+1, qr
#define STOP puts("Stop Here~");
using namespace std;
const int maxn = 8005;
int n,col[maxn<<2],vis[maxn<<2],ans[maxn<<2];
inline void down(int rt){
if(col[rt] != -1){
col[rt<<1] = col[rt<<1|1] = col[rt];
col[rt] = -1;
}
}
void update(int rt,int ql,int qr,int l,int r,int data){
if(l<=ql && qr<=r){
col[rt] = data;
return;
}
if(col[rt] == data) return;
if(col[rt]!=-1)down(rt);
int m = mid;
if(l <= m)update(lson,l,r,data);
if(r > m)update(rson,l,r,data);
}
void query(int rt,int ql,int qr){
if(col[rt]>=0){
for(int i=ql; i<=qr; ++i)
vis[i] = col[rt];
return;
}
if(ql!=qr && col[rt] == -1){
int m = mid;
query(lson);
query(rson);
}
}
int main(){
int a,b,c;
while(~scanf("%d",&n)){
memset(col,-1,sizeof(col));
for(int i=0; i<n; ++i){
scanf("%d%d%d",&a,&b,&c);
if(a>=b)continue;
update(1,1,8000,a+1,b,c);
}
mem(vis,-1);
query(1,1,8000);
int i = 1;
mem(ans,0);
while(i<maxn){
int color=vis[i], j=i+1;
if(color==-1){++i; continue;}
while(vis[j]==color && j<maxn) ++j;
++ans[color];
i=j;
}
for(int i=0; i<maxn; ++i)if(ans[i])
printf("%d %d\n",i,ans[i]);
puts("");
}
return 0;
}
本文详细介绍了线段树的基本概念及实现方式,包括构建过程、区间更新与查询操作,并通过具体示例展示了如何解决实际问题。
492

被折叠的 条评论
为什么被折叠?



