CF#391 3/7
B: 题意:从n个数中取出k个数,这k个数的gcd()不能为1,求最大的k。 总结:数据量很大,1e5,直接瞎搞会爆。类似于素数筛法,用数组标出现过的数,然后1~1e5的质数筛过去,碰到是这n个数中的就加上。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long ll; const int N = 1e5+10; int si[N],num[N]; bool mark[N]; void sieve_prime() { mes(mark,true); mark[0]=mark[1]=false; for(int i=2; i<=N; ++i) { if(mark[i]) { for(int j=i; j<N; j+=i) { mark[j]=false; if(si[j]!=0) num[i]+=si[j]; } } } } int main() { int n; mes(si,0); mes(num,0); scanf("%d", &n); int a; FF(i,1,n) { scanf("%d", &a); si[a]++; } sieve_prime(); int ans=1; F(i,2,N) if(num[i]!=0) { ans=max(ans, num[i]); } printf("%d\n", ans); return 0; }
C: 题意:n个区域,m个妖怪种类,在第i个区域有gi只妖怪,每只妖怪都有一个种类数mi。现在所有的妖怪都要进化一次,要求进化后每个区域的妖怪每个种类的数量不能变。进化程序要你设计,同一种类的妖怪进化后还得是同一个种类。求可能的方案数。 总结:种类x的妖怪进化到种类y,那么种类x,y的妖怪在所有区域的数量都应该是相同的。用vector比较即可。 注: 1、vector<int >A[N]; sort(A+1,A+1+m); // 按A[i].size()递增排序,不会改变A[i]中各个数的顺序。如.size()相同则按里面数的大小依次比较排序。 if(A[i]==A[i-1]); //只有两者各个数的大小、顺序都一致才相等。 2、题目意思区域yi对应多个种类xi,但这里反过来想,xi对应多个yi。 3、k个种类可以相互进化,这k个种类方案数就是k!,再与其它方案数相乘。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(a)) #define pb push_back #define INF 0x3f3f3f3f typedef long long ll; const int N = 1e6+10; const ll mod = 1e9+7; vector<int >A[N]; int main() { int n,m,gi; cin>>n>>m; FF(i,1,n) { cin>>gi; FF(j,1,gi) { int xi; cin>>xi; A[xi].pb(i); } } sort(A+1,A+1+m); ll ans=1,cnt=1; FF(i,2,m) { if(A[i]==A[i-1]) { ans=ans*(++cnt)%mod; } else { cnt=1; } } cout<<(ans+mod)%mod<<endl; return 0; }