zoukankan      html  css  js  c++  java
  • 第五周训练 | 二叉树+线段树

    A - Binary Tree Traversals

    记一个模板

    #include<iostream>
    using namespace std;
    typedef struct Tree{
        Tree *left;
        Tree *right;
        int value;
    }Tree;
     
    Tree *root;
     
     
    Tree* create(int *preorder,int *inorder,int n)
    {
        Tree *temp;
        for(int i=0;i<n;i++)
        {
            if(preorder[0]==inorder[i])
            {
                temp=(Tree*)malloc(sizeof(Tree));
                temp->value=inorder[i];          
                temp->left=create(preorder+1,inorder,i);
                temp->right=create(preorder+i+1,inorder+i+1,n-i-1);
                return temp;
            }
     
        }
        return NULL;
    }
     
    void postOrder(Tree *postTree)
    {
        if(postTree!=NULL)
        {
            postOrder(postTree->left);
            postOrder(postTree->right);
            if(postTree==root)
                printf("%d
    ",postTree->value);
            else
                printf("%d ",postTree->value);
        }
    }
     
    int main()
    {
        int n;
        int preorder[2010],inorder[2010];
        while(scanf("%d",&n)!=EOF)
        {
            root=NULL;
            for(int i=0;i<n;i++)
                scanf("%d",&preorder[i]);
            for(int i=0;i<n;i++)
                scanf("%d",&inorder[i]);
            root=create(preorder,inorder,n);
            postOrder(root);
     
        }
        return 0;
    }

    B - The order of a Tree

    bst树的创建,虽然不知道它有什么用。。。

     创建的时候每一次都是从根【总根】开始判断

    #include<iostream>
    #include<set>
    #define N  100001
    
    using namespace std;
    set<int>order;
    int k,ii;	
    int n;
    struct node
    {
    	node* l;
    	node* r;
    	int date;
    	node(int date,node *l=NULL,node *r=NULL):date(date),l(l),r(r){}
    };
    void create(node* &root,int val)
    {
    	if(!root)
    	{
    		root =new node(val);	
    	}
    	else if(val<root->date)
    	{
    		create(root->l,val); 
    	}
    	else
    	{
    		create(root->r,val);
    	}
    	
    }
    void preorder(node *root)
    {
    	if(root)
    	{
    		printf("%d%c",root->date,ii==n-1 ? '
    ':' ');
    		++ii;
    		preorder(root->l);
    		preorder(root->r); 
    	}
    }
    int main()
    {
    
    	node *root;
    	root=NULL;
    	cin>>n;
    	int temp;
    	for(int i=0;i<n;++i)
    	{
    		scanf("%d",&temp);
    		create(root,temp);
    	}
    	preorder(root);
    	return 0;
    } 
    

     C - 二叉搜索树

    #include<iostream>
    #include<cstring>
    using namespace std;
    #define MAX 200
    char tree1[MAX],tree2[MAX],n;
    string s;
    void create_tree(char tree[],char node)
    {
    	int root=1;
    	while(tree[root]!='')
    	{
    		if(node < tree[root]) {	root*=2; 	}
    		else 		{	root*=2; root++;		}
    	}
    	tree[root] = node;
    }
    int main()
    {
    	while(scanf("%d",&n)&&n) 
    	{
    		cin>>s;
    		memset(tree1,0,sizeof(tree1));
    		for(int i=0;i<s.length();++i)create_tree(tree1,s[i]);
    		for(int i=0;i<n;++i)
    		{
    			cin>>s;
    			memset(tree2,0,sizeof(tree2));
    			for(int i=0;i<s.length();++i) create_tree(tree2,s[i]);
    			if(memcmp(tree1,tree2,sizeof(tree1))==0) cout<<"YES
    ";
    			else cout<<"NO
    ";
    		}		
    	}
    	return 0;	
    } 
    

    D - Hardwood Species

     POJ - 2418 

    #include<iostream>
    #include<cstring>
    #include<map>
    #include<stdio.h>
    using namespace std;
    #define MAX 200
    string s;
    int main()
    {
    	map<string,int>mp;
    	int num=0;
    	while(getline(cin,s)!=NULL){	mp[s]++;num++; } 
    	map<string,int>::iterator i;
    	for(i=mp.begin();i!=mp.end();++i)
    	{
    		cout<<i->first;printf(" %.4f
    ",i->second*100.0/num);
    	}
    	return 0;	
    }

    E - Lost Cows 

    POJ - 2182  

    #include<iostream>
    #include<cstdio>
    /**
    二叉查找树:(又:二叉搜索树,二叉排序树)
    	它或者是一棵空树,或者是二叉树: 
    	若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 
    	若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
    线段树: 
    	是一种二叉搜索树,与区间树相似,
    	它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点
    分析: 剩下的数中 
    有n个数比他小,那么这个数的值是【拿去后的数中】n+1  
    */ 
    using namespace std;
    const int maxn=10000;
    int small[maxn],ans[maxn];
    struct node{
        int lc,rc,len;
    };
    node tree[maxn*3];//这里一开始数组开小了出现了rte 
    void build(int x,int lc,int rc)//构造一棵线段树 
    {
        tree[x].lc=lc,tree[x].rc=rc;//记录区间的端点值 
        tree[x].len=rc-lc+1;//记录区间长 
        if(lc==rc)return ;
        build(x*2,lc,(lc+rc)/2);//构造左子树 
        build(x*2+1,(lc+rc)/2+1,rc);//构造右子树 
    }
    int query(int base,int k)
    {
        tree[base].len--;//代表有数被拿走,这个区间的长度自减 
        if(tree[base].lc==tree[base].rc)return tree[base].lc;//当左右子树的端点值一样的时候戴白哦达到了叶子 
        if(k<=tree[base*2].len)// 区间的长度代表了数的个数 
    	{
            return query(base*2,k);//左边 
        }
        else
    	{
            return query(base*2+1,k-tree[base*2].len);//右边 
        }
    }
    int main(void)
    {
        int n;
        scanf("%d",&n); 
    	small[1]=0;
        for(int i=2;i<=n;i++)//输入数据 
    	{
            scanf("%d",&small[i]);
        }
        build(1,1,n);//建线段树 1-n从小到大
        for(int i=n;i>=1;i--)//从后往前找 
    	{
            ans[i]=query(1,small[i]+1);//从根开始,找区间长度为的small[i]+1
        }
        for(int i=1;i<=n;i++)
    	{
            printf("%d
    ",ans[i]);
        }
        return 0;
    }
    

    F - Mayor's posters 

    POJ - 2528[lazy] 

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<vector>
    #include<stack>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    #define md(l,r) (l+r)>>1
    #define rson(x) x<<1|1
    #define lson(x) x<<1
    #define endl '
    '
    #define sc(x) scanf("%d",&x)
    using namespace std;
    typedef long long LL;
    const int inf=0x3f3f3f3f;
    const int size=1e5+5;
    int Ledge[size],Redge[size];//放端点的 
    int lid[size],rid[size];
    vector<int > V;
    typedef long long LL;
    struct node 
    {
    	int l,r;
    	LL sum;
    	LL tag;
    } tree[size<<2];
    void build(int k,int l,int r) 
    {
    	tree[k].l=l,tree[k].r=r;
    	if(l==r)
    	{
    		tree[k].sum=0;
    		return ;
    	}
    	int mid(md(l,r));
    	build(lson(k),l,mid);
    	build(rson(k),mid+1,r);
    }
    void change(int k) 
    {
    	if(tree[k].l!=tree[k].r) 
    	{
    		int ls=lson(k),rs=rson(k);
    		tree[ls].sum=tree[k].tag;
    		tree[rs].sum=tree[k].tag;
    		tree[ls].tag=tree[k].tag;
    		tree[rs].tag=tree[k].tag;
    	}
    	tree[k].tag=0;
    }
    void Print()
    {
    	for(int i=0;i<20;++i)
    	{
    		cout<<i<<":"<<tree[i].l<<","<<tree[i].r<<","<<tree[i].sum<<","<<tree[i].tag<<endl;
    	}
     } 
    int query(int k,int l,int r)
    {
    	LL ans=inf;
    	if(tree[k].tag) change(k);//如果已经被染过色了,端点染色然后初始化 
    	if(tree[k].l==l&&tree[k].r==r) 
    	{
    		return tree[k].sum;
    	}
    	int mid=md(tree[k].l,tree[k].r);
    	if(r<=mid) ans=query(lson(k),l,r);//小区间在左边 
    	else if(l>=mid+1) ans=query(rson(k),l,r);//小区间在右边 
    	else ans=min(query(lson(k),l,mid),query(rson(k),mid+1,r));//mid在小区间内就把小区间分割 
    	return ans;
    }
    void add(int k,int l,int r,LL x) 
    {
    	
    	if(tree[k].tag) change(k);//端点染色判断 
    	if(tree[k].l==l&&tree[k].r==r) 
    	{
    		tree[k].sum=x;//区间内部涂色 
    		tree[k].tag=x;//tag用来记录这个区间属于哪个小区间 
    		return ;
    	}
    
    	int mid=md(tree[k].l,tree[k].r);
    	if(l>=mid+1) add(rson(k),l,r,x);
    	else if(r<=mid) add(lson(k),l,r,x);
    	else add(lson(k),l,mid,x),add(rson(k),mid+1,r,x);
    	tree[k].sum=min(tree[lson(k)].sum,tree[rson(k)].sum);//从左右端点选着那个小的作为这个区间的颜色 
    }
    
    int main() 
    {
    	int t;sc(t);
    	int ans=0;
    	while(t--)
    	{
    		int n;
    		ans=0;
    		V.clear();
    		memset(tree,0,sizeof(tree));
    		sc(n);
    		for(int i=0; i<n; i++) 
    		{
    			sc(Ledge[i]),sc(Redge[i]);//输入左右端点 
    			V.push_back(Ledge[i]),V.push_back(Redge[i]);
    		}
    		sort(V.begin(),V.end());//建立数组 
    		V.erase(unique(V.begin(),V.end()),V.end());//离散化——建新的数组 
    		/*
    		iterator erase( iterator _First, iterator _Last);
    			删除从_First开始到_Last位置(不包括_Last位置)的元素
    			返回值也是一个迭代器,指向最后一个删除元素的下一个位置。
    		unique函数的功能:”删除”序列中所有相邻的重复元素(只保留一个)。
    			此处的删除,并不是真的删除,而是指重复元素的位置被不重复的元素给占领了
    	   */ 
    	   
    		for(int i=0; i<n; i++) lid[i]=lower_bound(V.begin(),V.end(),Ledge[i])-V.begin()+1; //离散化——绑定新的区间 
    		for(int i=0; i<n; i++) rid[i]=lower_bound(V.begin(),V.end(),Redge[i])-V.begin()+1;
    		/*
    		lower_bound():int t=lower_bound(a+l,a+r,m)-a
    			在升序排列的a数组内二分查找[l,r)区间内的值为m的元素。
    			返回m在数组中的下标
    		*/
    		build(1,1,V.size()+1);//建线段树 
    		for(int i=n-1; i>=0; i--) //倒着来 
    		{
    			if(query(1,lid[i],rid[i])==0) //传入一个区间和根  
    			{
    				add(1,lid[i],rid[i],i);
    				ans++;
    			}
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    

    G - A Simple Problem with Integers 

    POJ - 3468 [lazy]

    #include<iostream>
    #include<stdio.h>
    using namespace std;
    typedef long long ll ;
    const int N=1e5+10;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    struct Node
    {
    	int l,r;
    	int mid()
    	{		return (l+r)>>1;    }	
    }tree[N<<2];
    ll sum[N<<2],add[N<<2];
    void PushUp(int rt)
    {
    	sum[rt] = sum[rt<<1]+sum[rt<<1|1];
     } 
    void PushDown(int rt,int m)
    {
    	if(add[rt])
    	{
    		add[rt<<1]+=add[rt];//左右节点添加延迟修改量,有可能有多个延迟修改量,这里用+= 
    		add[rt<<1|1]+=add[rt];
    		sum[rt<<1]+=add[rt]*(m-(m>>1));
    		sum[rt<<1|1]+=add[rt]*(m>>1);
    		add[rt]=0; 
    	}
    }
    void build(int l,int r,int rt) 
    {
    	tree[rt].l=l;
    	tree[rt].r=r;
    	add[rt]=0;
    	if(l==r)
    	{
    		scanf("%I64d",&sum[rt]);return;
    	}
    	int m=tree[rt].mid();
    	build(lson) ;
    	build(rson) ;
    	PushUp(rt);
    }
    void update(int c,int l,int r,int rt)
    {
    	if(tree[rt].l==l&&tree[rt].r==r)
    	{
    		add[rt]+=c;//给父节点打上一个lazy标签,子节点看情况修改 
    		sum[rt]+=(ll)c*(r-l+1);
    		return; 
    	}
    	if(tree[rt].l==tree[rt].r) return;
    	PushDown( rt , tree[rt].r - tree[rt].l + 1);
    	int m=tree[rt].mid();
    	if(r<=m) update(c,l,r,rt<<1);	
    	else if(l>m) update(c,l,r,rt<<1|1);
    	else
    	{
    		update(c,lson);	
    		update(c,rson);
    	}
    	PushUp(rt);
    }
    ll query(int l,int r,int rt) 
    {
    	if(l==tree[rt].l&&r==tree[rt].r) return sum[rt];
    	PushDown(rt,tree[rt].r-tree[rt].l+1);//一层 
    	int m=tree[rt].mid();
    	ll res = 0;
    	if(r<=m) res+=query(l,r,rt<<1);
    	else if(l>m) res+=query(l,r,rt<<1|1);
    	else
    	{
    		 res+=query(lson);
    		 res+=query(rson);
    	}
     	return res;
    }
    int main()
    {
    	int n,m;
    	while(~scanf("%d%d",&n,&m))
    	{
    		build(1,n,1);
    		while(m--)
    		{
    			char ch[2];
    			scanf("%s",ch);
    			int a,b,c;
    			if(ch[0]=='Q')
    			{
    				scanf("%d%d",&a,&b);
    				printf("%lld
    ",query(a,b,1));
    			}
    			else
    			{
    				scanf("%d%d%d",&a,&b,&c);
    				update(c,a,b,1);
    			} 
    		}
    	}
    	return 0;	
    } 

    H - 敌兵布阵

     HDU - 1166 

    #include<iostream>
    #include<cstring>
    #include<stdio.h>
    using namespace std;
    typedef long long ll ;
    const int N=1e5+10;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    struct Node
    {
        int l,r;
        int mid()
        {       return (l+r)>>1;    }
    }tree[N<<2];
    ll sum[N<<2],add[N<<2];
    void PushUp(int rt)
    {
        sum[rt] = sum[rt<<1]+sum[rt<<1|1];
    }
    void Init()
    {
    	memset(sum,0,sizeof(N<<2));
    	memset(add,0,sizeof(N<<2));
    	memset(tree,0,sizeof(N<<2));
    }
    void build(int l,int r,int rt)
    {
        tree[rt].l=l;tree[rt].r=r;
        if(l==r)
        {
            scanf("%I64d",&sum[rt]);return;
        }
        int m=tree[rt].mid();
        build(lson) ; build(rson) ;
        PushUp(rt);
    }
    void update(int c,int l,int r,int rt)
    {
        if(tree[rt].r==tree[rt].l) 
    	{
    		sum[rt]+=c;
    		return;
    	}
        int m=tree[rt].mid();
        if(r<=m) update(c,l,r,rt<<1); 
        else if(l>m) update(c,l,r,rt<<1|1);
        else
        {
            update(c,lson);
            update(c,rson);
        }
        PushUp(rt);
    }
    ll query(int l,int r,int rt)
    {
        if(l==tree[rt].l&&r==tree[rt].r) return sum[rt];
        int m=tree[rt].mid();ll res = 0;
        if(r<=m) res+=query(l,r,rt<<1);
        else if(l>m) res+=query(l,r,rt<<1|1);
        else
        {
             res+=query(lson);
             res+=query(rson);
        }
        return res;
    }
    int main()
    {
        int T,N;scanf("%d",&T);
        for(int i=1;i<=T;++i)
        {
        	scanf("%d",&N);build(1,N,1);
            string ch;
            int a,b,c; 
    		printf("Case %d:
    ",i);
            do
            {
            	cin>>ch;
    			if(ch=="Query")
    	        {
    	            scanf("%d%d",&a,&b);
    	            printf("%lld
    ",query(a,b,1));
    	        }
    	        else if(ch=="Add")
    	        {
    	            scanf("%d%d",&a,&b);
    	            update(b,a,a,1);
    	        }
    	        else if(ch=="Sub")
    			{
    	        	scanf("%d%d",&a,&b);
    	            update(-b,a,a,1);
    			}
    		}while(ch!="End");
    		Init();
        }
        return 0;  
    }

    I - Minimum Inversion Number

     HDU - 1394 

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn 5555
    #define inf 99999999
    int a[maxn];
    struct node{
    	int l,r,sum;//sum记录区间长 
    }tree[maxn*4];
    int ans=0;
    void pushup(int v)
    {
    	tree[v].sum=tree[v<<1].sum+tree[v<<1|1].sum;
    }
    void build(int l,int r,int v)
    {
    	tree[v].l=l;tree[v].r=r;tree[v].sum=0;
    	if(l==r) return;
    	int mid=(l+r)/2;
    	build(l,mid,v<<1);
    	build(mid+1,r,v<<1|1);
    }
    int query(int l,int r,int v)//求区间长度 
    {
    	if(l==tree[v].l&&r==tree[v].r) return tree[v].sum;
    	int mid=(tree[v].l+tree[v].r)/2;
    	if(r<=mid) return query(l,r,v<<1);
    	else if(l>mid) return query(l,r,v<<1|1);
    	else
    	{
    		return query(l,mid,v<<1)+query(mid+1,r,v<<1|1);
    	}
    }
    void update(int pos,int v)//更新区间长度 
    {
    	if(tree[v].l==tree[v].r){  tree[v].sum=1;return ; }
    	int mid=(tree[v].l+tree[v].r)/2;
    	if(pos<=mid) update(pos,v<<1);
    	else update(pos,v<<1|1);
    	pushup(v);
    }
    int main()
    {
    	int n;
    	while(~scanf("%d",&n))
    	{
    		memset(a,0,sizeof(a));
    		for(int i=0;i<n;i++) scanf("%d",&a[i]);
    		build(0,n-1,1);
    		int sum=0,min1=inf;
    		for(int i=0;i<n;i++)
    		{
    			ans=query(a[i],n-1,1);//计算a[i]对应的逆序数个数 =大于它的且已经出现过的数的个数
    			sum+=ans;
    			update(a[i],1);//将a[i]标记到数列中 	
    		}
    		for(int i=0;i<n;i++)
    		{
    			sum+=n-(a[i]+1)-a[i];
    			if(sum<min1) min1=sum;
    		}
    		printf("%d
    ",min1);
    	}
    }
    

    J - Just a Hook

     HDU - 1698 

     

      

  • 相关阅读:
    springcloud中常用的注解
    MySQL--Profiling和Trace使用
    MySQL Execution Plan--IN查询计划
    MySQL Config--参数system_time_zone和参数time_zone
    MySQL Replication--全局参数gtid_executed和gtid_purged
    MySQL Transaction--事务无法正常回滚导致的异常
    MySQL Execution Plan--数据排序操作
    MySQL Session--批量KILL会话
    MySQL Transaction--MySQL与SQL Server在可重复读事务隔离级别上的差异
    MySQL Transaction--事务相关查询
  • 原文地址:https://www.cnblogs.com/chrysanthemum/p/12004641.html
Copyright © 2011-2022 走看看