zoukankan      html  css  js  c++  java
  • 清北省选 DAY last 集锦

    这是题目描述的链接: http://lifecraft-mc.com/wp-content/uploads/2018/03/problems1.pdf

    (虽然这次没去清北,但还是厚颜无耻的做了一下这套题)

    T1:

        估计noip水平的选手都知道这个题可以用矩阵乘法水过去,但是作为一个还有8天就要省选的蒟蒻,我来提供一种娱乐做法:指数型生成函数。 像1和3这样必须出现且出现偶数次的数就可以用一个闭形式为 (e^x + e^-x)/2 - 1 的指数型生成函数表示,具体的推式子见代码。

    /*
        ANS = (e^x)^3 * ((e^x + e^-x)/2 -1)^2
            = e^3x * ((e^2x + 2 + e^-2x)/4 - (e^x + e^-x) + 1)
            = (e^5x + e^x + 2*e^3x)/4  - (e^4x + e^2x) +e^3x
            = (5^x + 2*3^x + 1)/4 - (4^x + 2^x) + 3^x
    */
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<vector>
    #include<cstdlib>
    #define ll long long
    using namespace std;
    const int ha=1000000007;
    const int inv=ha/2+1;
    int ans=0;
    ll n;
    
    inline int add(int x,int y){
    	x+=y;
    	return x>=ha?x-ha:x;
    }
    
    inline int DOUBLE(int x){
    	return add(x,x);
    }
    
    inline int ksm(int x,int y){
    	int an=1;
    	for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
    	return an;
    }
    
    int main(){
    //	freopen("number.in","r",stdin);
    //	freopen("number.out","w",stdout);
    	scanf("%lld",&n),n%=(ha-1);
    	ans=add(add(ksm(5,n),1),DOUBLE(ksm(3,n)));
    	ans=ans*(ll)inv%ha*(ll)inv%ha;
    	ans=add(ans,ha-add(ksm(2,n),ksm(4,n)));
    	ans=add(ans,ksm(3,n));
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

    T2:

        这也是一道比较基础的组合计数了2333,首先当我们确定多少行被选了奇数次的时候,多少列被选奇数次也就确定了(除了被选奇数次的行数*2==n 这种特殊情况),所以我们可以直接大力枚举选了多少奇行,然后乘上一些组合系数即可。

    /*
        设最后有x行y列被选了奇数次,那么满足:
            x*m + (n-2x)*y =k
            并且 (r-x) 和 (c-y) 都必须是偶数。
    	
    	然后此时的方案数就是:
    	    C(n,x) * C(m,y) * C(n+(r-x)/2-1,(r-x)/2) * C(m+(c-y)/2-1,(c-y)/2) 
    */
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<vector>
    #include<cstdlib>
    #define ll long long
    using namespace std;
    const int ha=1000000007;
    const int maxn=300000;
    int n,m,r,c,ans=0;
    int jc[maxn+5],ni[maxn+5];
    ll K;
    
    inline int add(int x,int y){
    	x+=y;
    	return x>=ha?x-ha:x;
    }
    
    inline int ksm(int x,int y){
    	int an=1;
    	for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
    	return an;
    }
    
    inline void init(){
    	jc[0]=1;
    	for(int i=1;i<=maxn;i++) jc[i]=jc[i-1]*(ll)i%ha;
    	ni[maxn]=ksm(jc[maxn],ha-2);
    	for(int i=maxn;i;i--) ni[i-1]=ni[i]*(ll)i%ha;
    }
    
    inline int C(int x,int y){
    	return jc[x]*(ll)ni[y]%ha*(ll)ni[x-y]%ha;
    }
    
    inline void solve(){
    	ll lef,O,y;
    	for(int i=r;i>=0;i-=2){
    		if(i>n) continue;
    		lef=K-i*(ll)m;
    		O=(n-2*i);
    		if(!O){
    			if(lef) continue;
    			int now=C(n,i)*(ll)C(m+c-1,c)%ha;
    			now=now*(ll)C(n+((r-i)>>1)-1,(r-i)>>1)%ha;
    			ans=add(ans,now);
    			continue;
    		}
    		
    		if(lef%O) continue;
    		y=lef/O;
    		if(y<0||y>c||y>m||((c-y)&1)) continue;
    		
    		int now=C(n,i)*(ll)C(m,y)%ha;
    		now=now*(ll)C(n+((r-i)>>1)-1,(r-i)>>1)%ha;
    		now=now*(ll)C(m+((c-y)>>1)-1,(c-y)>>1)%ha;
    		ans=add(ans,now);
    	}
    }
    
    int main(){
    	init();
    	scanf("%d%d%d%d%lld",&n,&m,&r,&c,&K);
    	solve();
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

    T3:

        一道比较好的扫描线题。

        我们知道当k==1的时候,这就是一个区间 mex 查询 (只不过0不被统计),而这个是一个经典扫描线问题。

        我们把那种方法扩展一下,先预处理出[1,i] 的所有答案,然后考虑左端点向右移动1个单位所带来的影响。当然这个也是可以预处理的,只不过完全可以不用后缀可持久化线段树去预处理(这是我一开始的想法),直接用一个set<>记录 i,i+1,,,i+k-1 这些数出现的最近的一个就可以了。虽然处理一个点的复杂度都是 O(k * log)的,但是set是O(k * log k)的,而后缀可持久化线段树查找是O(k *log n)的,而本题k远小于n,所以emmmmmm

    /*
        xjb扫描线即可 
    */
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<vector>
    #include<cstdlib>
    #include<set>
    #define ll long long
    using namespace std;
    const int maxn=200105;
    set<int> s;
    struct ask{
    	int L,R,num;
    	bool operator <(const ask &u)const{
    		return L<u.L;
    	}
    }q[maxn];
    int n,m,Q,k,ans[maxn],*pos,w,T[maxn];
    int a[maxn],las[maxn],le,ri,ops;
    int mn[maxn<<2|1],to[maxn][12];
    bool v[maxn];
    
    inline void prework(){
    	ops=1,v[n+1]=1;
    	for(int i=1,j;i<=m;i++){
    		v[a[i]]=1;
    		for(;ops<=n;ops++){
    			for(j=0;j<k;j++) if(v[ops+j]) break;
    			if(j==k) break;
    		}
    		T[i]=ops;
    	}
    	
    	for(int i=m;i;las[a[i]]=i,i--){
    		s.clear();
    		for(int j=0;j<k;j++) s.insert(las[a[i]+j]);
    		for(int j=0;j<k&&a[i]-j>0;s.erase(las[a[i]+k-j-1]),j++,s.insert(las[a[i]-j])){
    			to[i][j]=*s.lower_bound(0);
    		}
    	}
    }
    
    void update(int o,int l,int r){
    	if(l>=le&&r<=ri){
    		mn[o]=min(mn[o],w);
    		return;
    	}
    	int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
    	if(le<=mid) update(lc,l,mid);
    	if(ri>mid) update(rc,mid+1,r);
    }
    
    void query(int o,int l,int r){
    	*pos=min(*pos,mn[o]);
    	if(l==r) return;
    	int mid=l+r>>1,lc=o<<1,rc=(o<<1)|1;
    	if(le<=mid) query(lc,l,mid);
    	else query(rc,mid+1,r);
    }
    
    inline void add(int U){
    	for(int j=0;j<k&&a[U]-j>0;j++){
    		le=U+1,ri=to[U][j]-1,w=a[U]-j;
    		if(le<=ri) update(1,1,n);
    	}
    }
    
    inline void solve(){
    	for(int i=1;i<=Q;i++){
    		scanf("%d%d",&q[i].L,&q[i].R);
    		q[i].num=i;
    	}
    	sort(q+1,q+Q+1);
    	int now=1;
    	for(int i=1;i<=Q;i++){
    		while(now<q[i].L) add(now),now++;
    		pos=ans+q[i].num;
    		*pos=T[q[i].R];
    		le=q[i].R;
    		query(1,1,m);
    	}
    }
    
    inline void output(){
    	for(int i=1;i<=Q;i++){
    		if(ans[i]<=n) printf("%d
    ",ans[i]);
    		else puts("-1");
    	}
    } 
    
    int main(){
    	scanf("%d%d%d%d",&n,&m,&Q,&k);
    	for(int i=1;i<=m;i++) scanf("%d",a+i);
    	fill(las+1,las+n+1,m+1);
    	memset(mn,0x7f,sizeof(mn));
    	prework();
    	solve();
    	output();
    	return 0;
    } 
    

      

  • 相关阅读:
    3.16 使用Zookeeper对HDFS HA配置自动故障转移及测试
    4、html的body内标签之input系列
    Gym
    Gym
    Gym
    Gym
    Gym
    Big Event in HDU HDU1171 (多重背包)
    Coins POJ 1742 多重背包部分和
    HDU 1059 Dividing 多重背包
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8671396.html
Copyright © 2011-2022 走看看