zoukankan      html  css  js  c++  java
  • [JSOI2011]解题报告

    [JSOI2011]分特产

    一道组合数学+容斥的题目,考虑如何处理掉每个人至少一个这个限制,这时就要容斥一下有多少人没有分到即可,没分到的人数设为(i)

    每种特产分开算,便转化成了(n-i-1)块板子插入(a[i])个中,方案数为(C(n-i-a[i]-1,n-i-1))

    那么总的式子便为(sum_{i=0}^{n-1}(-1)^iC(n,i)prod_{j=1}^mC(n-i+a[i]-1,n-i-1))

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int mod=1e9+7;
    int jie[10003],cnt=-1,n,m,a[100003],cn,ans;
    int poww(int x,int p)
    {
    	if(p==0)
    		return 1;
    	int tmp=poww(x,p/2);
    	tmp=(tmp*tmp)%mod;
    	if(p%2==1)
    		tmp=(tmp*x)%mod;
    	return tmp;
    }
    int c(int nn,int mm)
    {
    	return jie[nn]*poww(jie[mm],mod-2)%mod*poww(jie[nn-mm],mod-2)%mod;
    }
    signed main()
    {
    	jie[0]=1;
    	for(int i=1; i<=10000; i++)
    		jie[i]=jie[i-1]*i%mod;
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=m;i++)
    		scanf("%lld",&a[i]);
    	for(int i=0;i<n;i++)
    	{
    		cnt*=-1,cn=1;
    		for(int j=1;j<=m;j++)
    			cn*=c(n-i+a[j]-1,n-i-1),cn%=mod;
    		ans+=cn*c(n,i)%mod*cnt%mod,ans=(ans+mod)%mod;
    	}
    	cout<<ans;
    	return 0;
    }
    

    [JSOI2011]棒棒糖

    这道题就是用主席树来维护这一个序列的权值,每次询问从([1,max{c[i]}])开始,每次递归([l,mid])([mid,r])查找在这个权值区间内的元素数量,如果数量乘2大于询问区间长度,就在这个权值区间内递归,知道找到一个符合要求的数或者找不到,然后剩下的就是主席树的基本操作

    #include<bits/stdc++.h>
    using namespace std;
    struct node
    {
    	int l1,r1,sum;
    }tr[5000003];
    int n,m,s,t,a[50003],gen[50003],summ,su,ans[50003],mp[50003];
    inline int rd()
    {
    	int x=0,p=1;
    	char a=getchar();
    	while((a<48||a>57)&&a!='-')
    		a=getchar();
    	if(a=='-')
    		p=-p,a=getchar();
    	while(a>47&&a<58)
    		x=(x<<1)+(x<<3)+(a&15),a=getchar();
    	return x*p;
    }
    int nbuild(int root)
    {
    	summ++,tr[summ]=tr[root];
    	return summ;
    }
    int build(int l,int r)
    {
    	summ++;
    	int root=summ,mid=(l+r)/2;
    	if(l==r)
    	{
    		tr[root].sum=0;
    		return root;
    	}
    	tr[root].l1=build(l,mid),tr[root].sum=0,tr[root].r1=build(mid+1,r);
    	return root;
    }
    int add(int root,int l,int r,int x)
    {
    	root=nbuild(root);
    	if(l==r)
    	{
    		tr[root].sum++;
    		return root;
    	}
    	int mid=(l+r)/2;
    	if(mid>=x)
    		tr[root].l1=add(tr[root].l1,l,mid,x);
    	else
    		tr[root].r1=add(tr[root].r1,mid+1,r,x);
    	tr[root].sum=tr[tr[root].l1].sum+tr[tr[root].r1].sum;
    	return root;
    }
    int ask(int root1,int root2,int l,int r,int x)
    {
    	if(l==r)
    		return l;
    	int mid=(l+r)/2;
    	if(2*(tr[tr[root2].l1].sum-tr[tr[root1].l1].sum)>x)
    		return ask(tr[root1].l1,tr[root2].l1,l,mid,x);
    	else if(2*(tr[tr[root2].r1].sum-tr[tr[root1].r1].sum)>x)
    		return ask(tr[root1].r1,tr[root2].r1,mid+1,r,x);
    	return 0;
    }
    int main()
    {
    	n=rd(),m=rd();
    	for(int i=1;i<=n;i++)
    	{
    		a[i]=rd();
    		if(mp[a[i]]==0)
    			su++,mp[a[i]]=su,ans[su]=a[i];
    		a[i]=mp[a[i]];
    	}
    	gen[0]=build(1,su);
    	for(int i=1;i<=n;i++)
    		gen[i]=add(gen[i-1],1,su,a[i]);
    	for(int i=1;i<=m;i++)
    	{
    		s=rd(),t=rd();
    		printf("%d
    ",ans[ask(gen[s-1],gen[t],1,su,t-s+1)]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    WCF 第四章 绑定 在多个绑定上暴露一个服务契约
    WCF 第五章 行为 事务跨操作事务流
    WCF 第五章 导出并发布元数据(服务行为)
    WCF 第五章 行为 通过配置文件暴露一个服务行为
    WCF 第五章 不支持会话的绑定的默认并发和实例
    WCF 第五章 并发和实例(服务行为)
    WCF 第五章 行为 总结
    WCF 第四章 绑定 绑定元素
    WCF 第五章 行为 事务之选择一个事务协议OleTx 或者WSAT
    WCF 第四章 绑定 比较各种绑定的性能和可扩展性
  • 原文地址:https://www.cnblogs.com/dzice/p/12244997.html
Copyright © 2011-2022 走看看