zoukankan      html  css  js  c++  java
  • csp-s模拟测试61砖块, 数字,甜圈题解

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

    砖块:

    直接模拟即可,map统计被覆盖的次数

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    using namespace std;
    const int MAXN=1005;
    int n,k,len,a,b,x,y,ans=0;//a,b:xia,x,y:shang
    char opt[MAXN];
    map< pair<int,int>,int>m;
    void workN(int &a,int &b,int &x,int &y){
    	if(a==x){
    		if(b==y) ++b,y+=k;
    		else b=++y;
    	}else ++b,++y;
    	for(int i=a;i<=x;++i){
    		for(int j=b;j<=y;++j){
    			pair<int,int>pa=make_pair(i,j);
    			if(m.find(pa)!=m.end()) m[pa]++;
    			else m[pa]=1;
    			ans=max(ans,m[pa]);
    		}
    	}
    }
    void workS(int &a,int &b,int &x,int &y){
    	if(a==x){
    		if(b==y) --y,b-=k;
    		else y=--b;
    	}else --b,--y;
    	for(int i=a;i<=x;++i){
    		for(int j=b;j<=y;++j){
    			pair<int,int>pa=make_pair(i,j);
    			if(m.find(pa)!=m.end()) m[pa]++;
    			else m[pa]=1;
    			ans=max(ans,m[pa]);
    		}
    	}
    }
    void workW(int &a,int &b,int &x,int &y){
    	if(b==y){
    		if(a==x) --x,a-=k;
    		else x=--a;
    	}else--a,--x;
    	for(int i=a;i<=x;++i){
    		for(int j=b;j<=y;++j){
    			pair<int,int>pa=make_pair(i,j);
    			if(m.find(pa)!=m.end()) m[pa]++;
    			else m[pa]=1;
    			ans=max(ans,m[pa]);
    		}
    	}
    }
    void workE(int &a,int &b,int &x,int &y){
    	if(b==y){
    		if(a==x) ++a,x+=k;
    		else a=++x;
    	}else ++x,++a;
    	for(int i=a;i<=x;++i){
    		for(int j=b;j<=y;++j){
    			pair<int,int>pa=make_pair(i,j);
    			if(m.find(pa)!=m.end()) m[pa]++;
    			else m[pa]=1;
    			ans=max(ans,m[pa]);
    		}
    	}
    }
    int main(){
    	scanf("%d",&n);
    	while(n--){
    		scanf("%d%s",&k,opt+1);
    		len=strlen(opt+1);
    		a=b=x=y=0;
    		m.clear();
    		m[make_pair(0,0)]=ans=1;
    		for(int i=1;i<=len;++i){
    			if(opt[i]=='N') workN(a,b,x,y);
    			else if(opt[i]=='S') workS(a,b,x,y);
    			else if(opt[i]=='W') workW(a,b,x,y);
    			else if(opt[i]=='E') workE(a,b,x,y);
    		}
    		if(a==x){
    			for(int i=b;i<=y;++i) printf("%d ",a);
    			puts("");
    			for(int i=b;i<=y;++i) printf("%d ",i);
    			puts("");
    			printf("%d
    ",ans);
    		}else{
    			for(int i=a;i<=x;++i) printf("%d ",i);
    			puts("");
    			for(int i=a;i<=x;++i) printf("%d ",b);
    			puts("");
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    }
    

    数字:

    显然不会

    粘个50分代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define int long long
     6 using namespace std;
     7 int n,k,T,fac[10000010];
     8 signed main(){
     9     fac[0]=1;
    10     for(int i=1;i<=10000000;++i){
    11         fac[i]=fac[i-1]*i;
    12         while(fac[i]%10==0&&fac[i]) fac[i]/=10;
    13         fac[i]%=10000000;
    14     }
    15     scanf("%lld",&T);
    16     while(T--){
    17         scanf("%lld %lld",&n,&k);
    18         while(fac[n]%10==0&&fac[n]) fac[n]/=10;
    19         if(k==1) printf("%.1lld
    ",fac[n]%10);
    20         if(k==2) printf("%.2lld
    ",fac[n]%100);
    21         if(k==3) printf("%.3lld
    ",fac[n]%1000);
    22     }
    23     return 0;
    24 }
    View Code

    甜圈:

    考虑一种不完美的算法,对于每次修改,我们在线段树上区间加,最后统计叶节点的和是否为$frac{k*(k+1)}{2}$,

    但是会有顺序的影响,1+3+2也会被我们算为合法

    为了排除顺序的影响,我们给它一个hash,每次区间加我们先让它乘上base,然后再加

    这样就是一个支持区间加,区间乘的线段树

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ull unsigned long long
    using namespace std;
    const int base=31;
    const int MAXN=200005;
    int n,k,t;
    ull tot;
    struct node{
    	ull laz_add,laz_mul,sum;
    	node(){laz_add=sum=0,laz_mul=1;}
    }tr[MAXN<<2];
    void down(int k,int l,int r){
        int mid=(l+r)>>1;
        if(tr[k].laz_mul!=1){
            int mid=(l+r)>>1;
            tr[k<<1].sum*=tr[k].laz_mul;
            tr[k<<1|1].sum*=tr[k].laz_mul;
            tr[k<<1].laz_mul*=tr[k].laz_mul;
            tr[k<<1|1].laz_mul*=tr[k].laz_mul;
            tr[k<<1].laz_add*=tr[k].laz_mul;
            tr[k<<1|1].laz_add*=tr[k].laz_mul;
            tr[k].laz_mul=1;
        }
        if(tr[k].laz_add!=0){
            tr[k<<1].sum+=(mid-l+1)*tr[k].laz_add;
            tr[k<<1|1].sum+=(r-mid)*tr[k].laz_add;
            tr[k<<1].laz_add+=tr[k].laz_add;
            tr[k<<1|1].laz_add+=tr[k].laz_add;
            tr[k].laz_add=0;
        }
    }
    void update(int k,int l,int r,int opl,int opr,int val){
        if(opl<=l&&r<=opr){
        	(tr[k].sum*=base)+=(r-l+1)*val;
            tr[k].laz_mul*=base;
            (tr[k].laz_add*=base)+=val;
            return ;
        }
        down(k,l,r);
        int mid=(l+r)>>1;
        if(opl<=mid) update(k<<1,l,mid,opl,opr,val);
        if(opr>mid) update(k<<1|1,mid+1,r,opl,opr,val);
        tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum);
    }
    int query(int k,int l,int r){
    	if(l==r){
    		if(tr[k].sum==tot) return 1;
    		else return 0;
    	}
    	down(k,l,r);
    	int mid=(l+r)>>1;
    	return query(k<<1,l,mid)+query(k<<1|1,mid+1,r);
    }
    signed main(){
    	scanf("%d%d%d",&n,&k,&t);
    	for(int i=1;i<=k;++i) tot=tot*base+i;
    	while(t--){
    		int l,r,x;
    		scanf("%d%d%d",&l,&r,&x);
    		update(1,1,n,l,r,x);
    	}
    	printf("%d
    ",query(1,1,n));
    	return 0;
    }
    

    另:区间加和区间乘的线段树板子:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define int long long
    using namespace std;
    const int MAXN=1e5+5;
    int n,m,p,a[MAXN];
    struct node{
        int sum,laz_add,laz_mul;
    }tr[MAXN<<2];
    void build(int k,int l,int r){
        tr[k].laz_add=0,tr[k].laz_mul=1;
        if(l==r){
            tr[k].sum=a[l]%p;
            return ;
        }
        int mid=(l+r)>>1;
        build(k<<1,l,mid),build(k<<1|1,mid+1,r);
        tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum)%p;
    }
    void down(int k,int l,int r){
        int mid=(l+r)>>1;
        if(tr[k].laz_mul!=1){
            int mid=(l+r)>>1;
            (tr[k<<1].sum*=tr[k].laz_mul%p)%=p;
            (tr[k<<1|1].sum*=tr[k].laz_mul%p)%=p;
            (tr[k<<1].laz_mul*=tr[k].laz_mul%p)%=p;
            (tr[k<<1|1].laz_mul*=tr[k].laz_mul%p)%=p;
            (tr[k<<1].laz_add*=tr[k].laz_mul%p)%=p;
            (tr[k<<1|1].laz_add*=tr[k].laz_mul%p)%=p;
            tr[k].laz_mul=1;
        }
        if(tr[k].laz_add!=0){
            (tr[k<<1].sum+=(mid-l+1)*tr[k].laz_add%p)%=p;
            (tr[k<<1|1].sum+=(r-mid)*tr[k].laz_add%p)%=p;
            (tr[k<<1].laz_add+=tr[k].laz_add)%=p;
            (tr[k<<1|1].laz_add+=tr[k].laz_add)%=p;
            tr[k].laz_add=0;
        }
    }
    void update_add(int k,int l,int r,int opl,int opr,int val){
        if(opl<=l&&r<=opr){
            (tr[k].sum+=(r-l+1)*val%p)%=p;
            (tr[k].laz_add+=val)%=p;
            return ;
        }
        down(k,l,r);
        int mid=(l+r)>>1;
        if(opl<=mid) update_add(k<<1,l,mid,opl,opr,val);
        if(opr>mid) update_add(k<<1|1,mid+1,r,opl,opr,val);
        tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum)%p;
    }
    void update_mul(int k,int l,int r,int opl,int opr,int val){
        if(opl<=l&&r<=opr){
            (tr[k].sum*=val%p)%=p;
            (tr[k].laz_mul*=val%p)%=p;
            (tr[k].laz_add*=val%p)%=p;
            return ;
        }
        down(k,l,r);
        int mid=(l+r)>>1;
        if(opl<=mid) update_mul(k<<1,l,mid,opl,opr,val);
        if(opr>mid) update_mul(k<<1|1,mid+1,r,opl,opr,val);
        tr[k].sum=(tr[k<<1].sum+tr[k<<1|1].sum)%p;
    }
    int query(int k,int l,int r,int opl,int opr){
        if(opl<=l&&r<=opr) return tr[k].sum%p;
        down(k,l,r);
        int mid=(l+r)>>1,res=0;
        if(opl<=mid) (res+=query(k<<1,l,mid,opl,opr))%=p;
        if(opr>mid) (res+=query(k<<1|1,mid+1,r,opl,opr))%=p;
        return res;
    }
    signed main(){
        //freopen("seq2.in","r",stdin);
        scanf("%lld%lld",&n,&p);
        for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
        build(1,1,n);
        scanf("%lld",&m);
        for(int i=1,opt,t,g,c,tot=0;i<=m;++i){
            scanf("%lld%lld%lld",&opt,&t,&g);
            if(opt==1){
                scanf("%lld",&c);
                update_mul(1,1,n,t,g,c);
            }
            else if(opt==2){
                scanf("%lld",&c);
                update_add(1,1,n,t,g,c);
            }
            else{
                printf("%lld
    ",query(1,1,n,t,g)%p);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    【巨杉数据库SequoiaDB】巨杉Tech | 四步走,快速诊断数据库集群状态
    【巨杉数据库SequoiaDB】巨杉Tech | 巨杉数据库数据高性能数据导入迁移实践
    【巨杉数据库SequoiaDB】SequoiaDB 巨杉数据库 v3.4 版本正式发布
    【巨杉数据库Sequoiadb】巨杉⼯具系列之一 | ⼤对象存储⼯具sdblobtool
    easynetq发布订阅demo实现注意事项
    C#的排序Sort和OrderBy扩展方法
    程序员,不要急于学习编程语言,先学会如何解决问题(转)
    .Net异步关键字async/await的最终理解
    浅谈C#常用集合类的实现以及基本操作复杂度
    C# SortedDictionary以及SortedList的浅谈
  • 原文地址:https://www.cnblogs.com/Juve/p/11626361.html
Copyright © 2011-2022 走看看