zoukankan      html  css  js  c++  java
  • 线段树

    ACM大牛的线段树总结。看完就懂了。(代码也是抄自那里。。

    hdu1166 (基本线段树(然后表示不明白为什么输出优化WA了

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,n) for(int i=1;i<=n;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    #define lson l,m,x<<1
    #define rson m+1,r,x<<1|1
    int read(){
    	int x=0;char c=getchar();bool f=true;
    	while(!isdigit(c)) {
    		if(c=='-') f=false;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return f?x:-x;
    }
    void print(int x){
    	char ch[10];int cur=0;
    	if(x<0) putchar('-'),x=-x;
    	while(x) ch[++cur]=x%10+'0',x/=10;
    	for(int i=cur;i;i--) putchar(ch[i]);
    	putchar('
    ');
    	return ;
    }
    const int nmax=50005;
    const int inf=0x7f7f7f7f;
    int sum[nmax<<2];
    void pushup(int x){
    	sum[x]=sum[x<<1]+sum[x<<1|1];return ;
    }
    int query(int l,int r,int x,int tl,int tr){
    	if(tl<=l&&tr>=r) return sum[x];
    	int m=(l+r)>>1;int tmp=0;
    	if(tl<=m) tmp+=query(lson,tl,tr);
    	if(tr>m) tmp+=query(rson,tl,tr);
    	return tmp;
    }
    void build(int l,int r,int x){
    	if(l==r) {
    		sum[x]=read();return ;
    	}
    	int m=(l+r)>>1;
    	build(lson);build(rson);pushup(x);
    }
    void update(int l,int r,int x,int p,int add){
    	if(l==r) {
    		sum[x]+=add;return ;
    	}
    	int m=(l+r)>>1;
    	p<=m?update(lson,p,add):update(rson,p,add);
    	pushup(x);
    }
    int main(){
    	int t=read();
    	rep(i,t){
    		printf("Case %d:
    ",i);
    		int n=read();
    		build(1,n,1);
    		char c[10];
    		while(scanf("%s",c)){
    			if(c[0]=='E') break;
    			int a=read(),b=read();
    			if(c[0]=='Q') printf("%d
    ",query(1,n,1,a,b));//print(query(1,n,1,a,b));
    			else if(c[0]=='S') update(1,n,1,a,-b);
    			else update(1,n,1,a,b);
    		}
    	}
    	return 0;
    }
    

     hdu1754 (裸

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,n) for(int i=1;i<=n;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define lson l,m,x<<1
    #define rson m+1,r,x<<1|1
    int read(){
    	int x=0;char c=getchar();bool f=true;
    	while(!isdigit(c)){
    		if(c=='-') f=false;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return f?x:-x;
    }
    const int nmax=200005;
    const int inf=0x7f7f7f7f;
    int sum[nmax<<2];
    void pushup(int x){
    	sum[x]=max(sum[x<<1],sum[x<<1|1]);
    }
    int qmax(int l,int r,int x,int tl,int tr){
    	if(tl<=l&&tr>=r) return sum[x];
    	int m=(l+r)>>1;int tmp=-inf;
    	if(tl<=m) tmp=max(tmp,qmax(lson,tl,tr));
    	if(tr>m) tmp=max(tmp,qmax(rson,tl,tr));
    	return tmp;
    }
    void update(int l,int r,int x,int p,int add){
    	if(l==r) {
    		sum[x]=add;return ;
    	}
    	int m=(l+r)>>1;
    	p<=m?update(lson,p,add):update(rson,p,add);
    	pushup(x);
    }
    void build(int l,int r,int x){
    	if(l==r) {
    		sum[x]=read();return ;
    	}
    	int m=(l+r)>>1;
    	build(lson);build(rson);pushup(x);
    }
    int main(){
    	int n,m;
    	while(scanf("%d%d",&n,&m)==2){
    		build(1,n,1);
    		rep(i,m){
    			char c=getchar();int a=read(),b=read();
    			if(c=='Q') printf("%d
    ",qmax(1,n,1,a,b));
    			else update(1,n,1,a,b);
    		}
    	}
    	return 0;
    }
    

     hdu1698:区间修改(打标志。。。然后输出的时候.没有输出WA了。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,n) for(int i=1;i<=n;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define lson l,m,x<<1
    #define rson m+1,r,x<<1|1
    int read(){
    	int x=0;char c=getchar();bool f=true;
    	while(!isdigit(c)){
    		if(c=='-') f=false;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return f?x:-x;
    }
    const int nmax=100005;
    int sum[nmax<<2],col[nmax<<2];
    void pushup(int x){
    	sum[x]=sum[x<<1]+sum[x<<1|1];
    }
    void pushdown(int x,int cnt){
    	if(col[x]){
    		col[x<<1]=col[x<<1|1]=col[x];
    		sum[x<<1]=col[x]*(cnt-(cnt>>1));
    		sum[x<<1|1]=col[x]*(cnt>>1);
    		col[x]=0;
    	}
    }
    void build(int l,int r,int x){
    	if(l==r) {
    		sum[x]=1;return ;
    	}
    	int m=(l+r)>>1;
    	build(lson);build(rson);pushup(x);
    }
    void update(int tl,int tr,int p,int l,int r,int x){
    	if(tl<=l&&r<=tr) {
    		sum[x]=p*(r-l+1);col[x]=p;return ;
    	}
    	pushdown(x,r-l+1);
    	int m=(l+r)>>1;
    	if(tl<=m) update(tl,tr,p,lson);
    	if(tr>m) update(tl,tr,p,rson);
    	pushup(x);
    }
    int main(){
    	int t=read();
    	rep(i,t){
    		int n=read(),m=read();
    		clr(col,0);
    		build(1,n,1);
    		rep(j,m){
    			int a=read(),b=read(),c=read();update(a,b,c,1,n,1);
    		}
    		printf("Case %d: The total value of the hook is %d.
    ",i,sum[1]);
    	}
    	return 0;
    }
    

     poj3468:同样是区间修改。(然后query的时候忘了pushdown了。手动模拟证实不是update写错。。然后一看query。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,n) for(int i=1;i<=n;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define lson l,m,x<<1
    #define rson m+1,r,x<<1|1
    #define ll long long
    int read(){
    	int x=0;char c=getchar();bool f=true;
    	while(!isdigit(c)){
    		if(c=='-') f=false;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return f?x:-x;
    }
    const int nmax=100005;
    ll sum[nmax<<2],col[nmax<<2];
    void pushup(int x){
    	sum[x]=sum[x<<1]+sum[x<<1|1];
    }
    void build(int l,int r,int x){
    	if(l==r){
    		sum[x]=read();return ;
    	}
    	int m=(l+r)>>1;
    	build(lson);build(rson);pushup(x);
    }
    void pushdown(int x,int cnt){
    	if(col[x]){
    		ll tmp=col[x];
    		col[x<<1]+=tmp;col[x<<1|1]+=tmp;
    		sum[x<<1]+=tmp*(cnt-(cnt>>1));
    		sum[x<<1|1]+=tmp*(cnt>>1);
    		col[x]=0;
    	}
    	return ;
    }
    void update(int tl,int tr,int p,int l,int r,int x){
    	if(tl<=l&&tr>=r) {
    		sum[x]+=(ll)(r-l+1)*p;col[x]+=p;return ;
    	}
    	pushdown(x,r-l+1);
    	int m=(l+r)>>1;
    	if(tl<=m) update(tl,tr,p,lson);
    	if(tr>m) update(tl,tr,p,rson);
    	pushup(x);
    }
    ll query(int tl,int tr,int l,int r,int x){
    	if(tl<=l&&r<=tr) return sum[x];
    	pushdown(x,r-l+1);
    	int m=(l+r)>>1;ll ans=0;
    	if(tl<=m) ans+=query(tl,tr,lson);
    	if(tr>m) ans+=query(tl,tr,rson);
    	return ans;
    }
    int main(){
    	int n=read(),m=read();
    	build(1,n,1);clr(col,0);
    //	cout<<sum[1];
    //	printf("%lld
    ",query(1,n,1,n,1));
    //	rep(i,4*n) printf("%d ",sum[i]);
    	rep(i,m){
    		char ch=getchar();
    		if(ch=='Q') {
    			int a=read(),b=read();
    			printf("%lld
    ",query(a,b,1,n,1));
    		}
    		else{
    			int a=read(),b=read(),c=read();
    			update(a,b,c,1,n,1);
    		//	rep(j,n*4) printf("%d:%d
    ",j,sum[j]);
    		}
    	}
    	return 0;
    }
    

     hdu1394:(其实如果不是数据范围特殊的话根本不能用线段树做。。。逆序对。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,n) for(int i=1;i<=n;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define lson l,m,x<<1
    #define rson m+1,r,x<<1|1
    int read(){
    	int x=0;char c=getchar();bool f=true;
    	while(!isdigit(c)){
    		if(c=='-') f=false;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return f?x:-x;
    }
    const int nmax=5005;
    int sum[nmax<<2],x[nmax];
    void pushup(int x){
    	sum[x]=sum[x<<1]+sum[x<<1|1];
    }
    void build(int l,int r,int x){
    	if(l==r) return ;
    	int m=(l+r)>>1;
    	build(lson);build(rson);pushup(x);
    }
    int query(int tl,int tr,int l,int r,int x){
    	if(tl<=l&&tr>=r) return sum[x];
    	int m=(l+r)>>1;int ans=0;
    	if(tl<=m) ans+=query(tl,tr,lson);
    	if(tr>m) ans+=query(tl,tr,rson);
    	return ans;
    }
    void update(int p,int tmp,int l,int r,int x){
    	if(l==r) {
    		sum[x]=tmp;return ;
    	}
    	int m=(l+r)>>1;
    	p<=m?update(p,tmp,lson):update(p,tmp,rson);
    	pushup(x);
    	return ;
    }
    int main(){
    	int n;
    	while(scanf("%d",&n)==1){
    		build(1,n,1);clr(sum,0);
    		int cnt=0;
    		rep(i,n){
    			x[i]=read();x[i]++;
    			if(x[i]!=n) 	cnt+=query(x[i]+1,n,1,n,1);
    			update(x[i],1,1,n,1);
    
    		}
    		int ans=cnt;
    	//	cout<<cnt<<endl;
    		rep(i,n){
    			cnt=cnt-2*x[i]+n+1;
    			ans=min(ans,cnt);
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

     poj2528:线段树+离散化。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,n) for(int i=1;i<=n;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define lson l,m,x<<1
    #define rson m+1,r,x<<1|1
    int read(){
    	int x=0;char c=getchar();bool f=true;
    	while(!isdigit(c)){
    		if(c=='-') f=false;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return f?x:-x;
    }
    const int nmax=10005;
    int col[nmax<<4],v[nmax],x[nmax<<2],lx[nmax],rx[nmax];
    int find(int l,int r,int a){
    	/*int m=(l+r)>>1;
    	if(x[m]==a) return m;
    	if(x[m]<a) return find(m+1,r,a);
    	return find(l,m,a);*/
    	while(l<=r){
    		int m=(l+r)>>1;
    		if(x[m]==a) return m;
    		if(x[m]<a) l=m+1;
    		else r=m-1;
    	}
    	return -1;
    }
    void pushdown(int x){
    	if(col[x]) col[x<<1]=col[x<<1|1]=col[x],col[x]=0; //注意if 
    }
    void update(int tl,int tr,int p,int l,int r,int x){
    	if(tl<=l&&tr>=r) {
    		col[x]=p;return ;
    	}
    	pushdown(x);
    	int m=(l+r)>>1;
    	if(tl<=m) update(tl,tr,p,lson);
    	if(tr>m) update(tl,tr,p,rson);
    }
    void query(int l,int r,int x){
    	if(col[x]) {
    		v[col[x]]=1;
    		return ;
    	}
    	if(l==r) return ;
    	int m=(l+r)>>1;
    	query(lson);query(rson);return ;
    }
    int main(){
    	int t=read();
    	while(t--){
    		int n=read();x[0]=0;
    		rep(i,n) x[++x[0]]=lx[i]=read(),x[++x[0]]=rx[i]=read();
    		sort(x+1,x+n+n+1);
    		x[0]=0;
    		rep(i,n+n) if(x[i]!=x[i-1]) x[++x[0]]=x[i];
    	//	rep(i,x[0]) printf("%d ",x[i]); cout<<endl;
    		int cur=x[0];
    		rep(i,x[0]-1) if(x[i+1]-x[i]>1) x[++cur]=x[i]+1;
    		sort(x+1,x+cur+1);
    	//	rep(i,cur) printf("%d ",x[i]);cout<<endl;
    	    clr(col,0);
    		rep(i,n){
    			int l=find(1,cur,lx[i]);
    			int r=find(1,cur,rx[i]);
    			update(l,r,i,1,cur,1);
    		//	printf("%d %d
    ",l,r);
    		}
    		int ans=0;clr(v,0);query(1,cur,1);
    		rep(i,n) if(v[i]) ans++;
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

     poj3667:求连续最长区间。维护lsum rsum msum即可。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,n) for(int i=1;i<=n;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define lson l,m,x<<1
    #define rson m+1,r,x<<1|1
    int read(){
    	int x=0;char c=getchar();bool f=true;
    	while(!isdigit(c)) {
    		if(c=='-') f=false;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return f?x:-x;
    }
    const int nmax=50005;
    const int inf=0x7f7f7f7f;
    int col[nmax<<2],lsum[nmax<<2],rsum[nmax<<2],msum[nmax<<2];
    void pushup(int x,int cnt){
    	lsum[x]=(lsum[x<<1]==(cnt-(cnt>>1)))?lsum[x<<1]+lsum[x<<1|1]:lsum[x<<1];
    	rsum[x]=(rsum[x<<1|1]==(cnt>>1))?rsum[x<<1|1]+rsum[x<<1]:rsum[x<<1|1];
    	msum[x]=max(rsum[x<<1]+lsum[x<<1|1],max(msum[x<<1|1],msum[x<<1]));
    }
    void pushdown(int x,int cnt){
    	if(col[x]!=-1){
    		col[x<<1]=col[x<<1|1]=col[x];
    		lsum[x<<1]=rsum[x<<1]=msum[x<<1]=col[x]?0:cnt-(cnt>>1);
    		lsum[x<<1|1]=rsum[x<<1|1]=msum[x<<1|1]=col[x]?0:(cnt>>1);
    		col[x]=-1;
    	}
    }
    void build(int l,int r,int x){
    	col[x]=-1,msum[x]=lsum[x]=rsum[x]=r-l+1; //col[x]!=0
    	if(l==r) return ;
    	int m=(l+r)>>1;build(lson);build(rson);
    }
    void update(int tl,int tr,int p,int l,int r,int x){
    	if(tl<=l&&tr>=r){
    		if(p) col[x]=p,lsum[x]=rsum[x]=msum[x]=0;
    		else col[x]=p,lsum[x]=rsum[x]=msum[x]=r-l+1;
    	}else{
    		pushdown(x,r-l+1);
    		int m=(l+r)>>1;
    		if(tl<=m) update(tl,tr,p,lson);
    		if(tr>m) update(tl,tr,p,rson);
    		pushup(x,r-l+1);
    	}
    }
    int query(int cnt,int l,int r,int x){
    	if(l==r) return l;
    	pushdown(x,r-l+1);   //look out
    	int m=(l+r)>>1;
    	if(msum[x<<1]>=cnt) return query(cnt,lson);
    	if(rsum[x<<1]+lsum[x<<1|1]>=cnt) return m-rsum[x<<1]+1;
    	return query(cnt,rson);
    }
    int main(){
    	int n=read(),m=read();build(1,n,1);
    //	rep(i,n<<2) printf("%d:%d %d %d %d
    ",i,lsum[i],rsum[i],msum[i],col[i]);
    	rep(i,m){
    		int p=read();
    		if(p==1) {
    			int tmp=read();
    			if(msum[1]<tmp) puts("0");
    			else {
    				int cur=query(tmp,1,n,1);printf("%d
    ",cur);
    				update(cur,tmp+cur-1,1,1,n,1);
    			}
    		}else{
    			int a=read(),b=read();update(a,a+b-1,0,1,n,1);
    		}
    	}
    	return 0;
    }
    

      hdu2828:题目看起来挺水的。但是update的时候不知道怎么判断QAQ。。。就是不断的插入一些数,如果有了就放在他后面。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,n) for(int i=1;i<=n;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define lson l,m,x<<1
    #define rson m+1,r,x<<1|1
    int read(){
    	int x=0;char c=getchar();bool f=true;
    	while(!isdigit(c)){
    		if(c=='-') f=false;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return f?x:-x;
    }
    const int nmax=200005;
    const int inf=0x7f7f7f7f;
    int sum[nmax<<2],t[nmax<<2],a[nmax],b[nmax];
    void build(int l,int r,int x){
    	if(l==r) {
    		sum[x]=1;return ;
    	}
    	int m=(l+r)>>1;build(lson);build(rson);sum[x]=sum[x<<1]+sum[x<<1|1];
    }
    /*void update(int p,int add,int l,int r,int x){
    	if(l==r){
    		sum[x]=0;t[x]=add;return ;
    	}
    	int m=(l+r)>>1;
    	if(p>m||p<=m&&!sum[x<<1]) update(m+1,add,rson);
    	else update(p,add,lson);sum[x]=sum[x<<1]+sum[x<<1|1];
    }*/
    void update(int p,int add,int l,int r,int x){
    	if(l==r){
    		sum[x]=0;t[x]=add;return ;
    	}
    	int m=(l+r)>>1;
    	sum[x<<1]>=p?update(p,add,lson):update(p-sum[x<<1],add,rson);
    	sum[x]=sum[x<<1]+sum[x<<1|1];
    }
    void query(int l,int r,int x){
    	if(l==r) {
    		printf("%d ",t[x]);return ;
    	}
    	int m=(l+r)>>1;query(lson);query(rson);return ;
    }
    int main(){
    	int n;
    	while(scanf("%d",&n)==1){
    		build(1,n,1);
    		rep(i,n) a[i]=read(),b[i]=read();
    		for(int i=n;i;i--) update(a[i]+1,b[i],1,n,1)/*,printf("%d
    ",sum[2])*/;
    		query(1,n,1);printf("
    ");
    	}
    	return 0;
    } 
    

      

  • 相关阅读:
    AngularJs学习笔记Understanding the Controller Component
    AngularJs学习笔记Dependency Injection(DI,依赖注入)
    AngularJs学习笔记Forms
    AngularJs学习笔记Modules
    AngularJs学习笔记IE Compatibility 兼容老版本IE
    Oracle trigger Demo
    Debugging tips in VS
    Adding a Strong Name to an existing DLL that you don't have the source to
    Webservice
    Tips to import DB dump of a big size
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5634252.html
Copyright © 2011-2022 走看看