• HZOI20190908模拟40 队长快跑,影魔,抛硬币 题解


    题面:https://www.cnblogs.com/Juve/articles/11487699.html

    队长快跑:

    权值线段树与dp

    yy的不错

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int MAXN=1e5+5;
    int n,a[MAXN],b[MAXN],ans=0,lsh[MAXN<<1],cnt,tot=0;
    struct node{
    	int l,r,laz,mx;
    }tr[MAXN<<4];
    void build(int k,int l,int r){
    	tr[k].l=l,tr[k].r=r;
    	if(l==r){
    		tr[k].mx=0;
    		return ;
    	}
    	int mid=(l+r)>>1;
    	build(k<<1,l,mid);
    	build(k<<1|1,mid+1,r);
    }
    void down(int k){
    	tr[k<<1].laz+=tr[k].laz;
    	tr[k<<1|1].laz+=tr[k].laz;
    	tr[k<<1].mx+=tr[k].laz;
    	tr[k<<1|1].mx+=tr[k].laz;
    	tr[k].laz=0;
    }
    void pushup(int k){
    	tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
    }
    int query_max(int k,int opl,int opr){
    	int l=tr[k].l,r=tr[k].r;
    	if(opl<=l&&r<=opr) return tr[k].mx;
    	if(tr[k].laz) down(k);
    	int mid=(l+r)>>1,res=0;
    	if(opl<=mid) res=max(res,query_max(k<<1,opl,opr));
    	if(opr>mid) res=max(res,query_max(k<<1|1,opl,opr));
    	return res;
    }
    void update(int k,int opt,int val){
    	int l=tr[k].l,r=tr[k].r;
    	if(l==r){
    		tr[k].mx=max(tr[k].mx,val);
    		return ;
    	}
    	if(tr[k].laz) down(k);
    	int mid=(l+r)>>1;
    	if(opt<=mid) update(k<<1,opt,val);
    	else update(k<<1|1,opt,val);
    	pushup(k);
    }
    void change(int k,int opl,int opr){
    	int l=tr[k].l,r=tr[k].r;
    	if(opl<=l&&r<=opr){
    		++tr[k].mx;
    		++tr[k].laz;
    		return ;
    	}
    	if(tr[k].laz) down(k);
    	int mid=(l+r)>>1;
    	if(opl<=mid) change(k<<1,opl,opr);
    	if(opr>mid) change(k<<1|1,opl,opr);
    	pushup(k);
    }
    signed main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		scanf("%d%d",&a[i],&b[i]);
    		lsh[++tot]=a[i],lsh[++tot]=b[i];
    	}
    	sort(lsh+1,lsh+tot+1);
    	cnt=unique(lsh+1,lsh+tot+1)-lsh;
    	for(int i=1;i<=n;++i){
    		a[i]=lower_bound(lsh+1,lsh+cnt+1,a[i])-lsh;
    		b[i]=lower_bound(lsh+1,lsh+cnt+1,b[i])-lsh;
    	}
    	build(1,1,cnt);
    	for(int i=n;i>=1;--i){
    		if(a[i]>b[i]){
    			int p=query_max(1,1,b[i]-1)+1;
    			update(1,b[i],p);
    			change(1,b[i]+1,a[i]);
    		}else{
    			int p=query_max(1,1,a[i]-1)+1;
    			update(1,b[i]+1,p);
    		}
    	}
    	printf("%d
    ",tr[1].mx);
        return 0;
    }
    

    影魔:

    主席树,每个深度建树

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MAXN=1e5+5;
    int n,m,c[MAXN],fa[MAXN],ans,tot=0;
    int to[MAXN<<1],nxt[MAXN<<1],pre[MAXN],cnt=0;
    void add(int u,int v){
    	++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt;
    }
    int root1[MAXN],root2[MAXN];
    struct node{
    	int ls,rs,val;
    }tr[MAXN<<7];
    void build(int &k,int l,int r,int pos,int val){
    	k=++tot;
        if(l==r){
            tr[k].val=val;
            return ;
        }
        int mid=(l+r)>>1;
        if(pos<=mid) build(tr[k].ls,l,mid,pos,val);
        else build(tr[k].rs,mid+1,r,pos,val);
    }
    void update(int &k,int l,int r,int pos,int val){
    	++tot;
        tr[tot]=tr[k];
        k=tot;
        tr[k].val+=val;
        if(l==r) return ;
        int mid=(l+r)>>1;
        if(pos<=mid) update(tr[k].ls,l,mid,pos,val);
        else update(tr[k].rs,mid+1,r,pos,val);
    }
    int merge1(int x,int y,int l,int r,int p){
    	if(!x||!y) return x+y;
        int k=++tot;
        if(l==r){
            tr[k].val=min(tr[x].val,tr[y].val);
            update(root2[p],1,n,max(tr[x].val,tr[y].val),-1);
            return k;
        }
        int mid=(l+r)>>1;
        tr[k].ls=merge1(tr[x].ls,tr[y].ls,l,mid,p);
        tr[k].rs=merge1(tr[x].rs,tr[y].rs,mid+1,r,p);
        return k;
    }
    int merge2(int x,int y,int l,int r){
    	if(!x||!y) return x+y;
        int k=++tot;
        tr[k].val=tr[x].val+tr[y].val;
        int mid=(l+r)>>1;
        tr[k].ls=merge2(tr[x].ls,tr[y].ls,l,mid);
        tr[k].rs=merge2(tr[x].rs,tr[y].rs,mid+1,r);
        return k;
    }
    int query(int k,int l,int r,int opl,int opr){
        if(opl<=l&&r<=opr) return tr[k].val;
        int res=0,mid=(l+r)>>1;
        if(opl<=mid) res+=query(tr[k].ls,l,mid,opl,opr);
        if(opr>mid) res+=query(tr[k].rs,mid+1,r,opl,opr);
        return res;
    }
    int deep[MAXN];
    void dfs(int x,int fa){
    	build(root1[x],1,n,c[x],deep[x]);
        update(root2[x],1,n,deep[x],1);
        for(int i=pre[x];i;i=nxt[i]){
            int y=to[i];
            if(y==fa) continue;
            deep[y]=deep[x]+1;
            dfs(y,x);
            root1[x]=merge1(root1[x],root1[y],1,n,x);
            root2[x]=merge2(root2[x],root2[y],1,n);
        }
    }
    signed main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i){
    		scanf("%d",&c[i]);
    	}
    	for(int i=2;i<=n;++i){
    		scanf("%d",&fa[i]);
    		add(fa[i],i);
    	}
    	deep[1]=1;
    	dfs(1,0);
    	for(int i=1,k,dis;i<=m;++i){
            scanf("%d%d",&k,&dis);
            ans=query(root2[k],1,n,deep[k],deep[k]+dis);
            printf("%d
    ",ans);
        }
        return 0;
    }
    

    抛硬币:

    乱搞dp

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int MAXN=3005;
    const int mod=998244353;
    int l,len,f[MAXN][MAXN],s[MAXN];
    char ch[MAXN];
    signed main(){
    	scanf("%s",ch+1);
        scanf("%d",&l);
        len=strlen(ch+1);
    	//cout<<len<<endl;
    	for(int i=1;i<=len;++i){
    		f[i][0]=1;
    		for(int j=i-1;j>=1;--j){
    			if(ch[j]==ch[i]){
    				s[i]=j;
    				break;
    			}
    		}
    	}
    	//for(int i=1;i<=len;++i) cout<<s[i]<<endl;
        f[0][0]=1;
        for(int i=1;i<=len;++i){
    		for(int j=1;j<=l;++j){
    			if(s[i]!=0) f[i][j]=((f[i-1][j]+f[i-1][j-1]-f[s[i]-1][j-1])%mod+mod)%mod;
    			else f[i][j]=(f[i-1][j]+f[i-1][j-1])%mod;
    		}
    	}
    	printf("%d
    ",f[len][l]);
    	return 0;
    }
    
  • 相关阅读:
    3、字节流输入输出实现文件的copy
    2、io的读出数据到文件中的内容(文件字节输出流)
    1、io的读取文件中的内容(文件字节输入流)
    10 linux中运行jar
    Linux 部署 iSCSI 客户端配置(Linux)
    Linux 部署 iSCSI 服务端
    Linux上使用iSCSI概述
    SSH实现免密登陆
    源码安装Python3
    Windows(受控主机)上配置
  • 原文地址:https://www.cnblogs.com/Juve/p/11487702.html
Copyright © 2020-2023  润新知