D题链接:http://codeforces.com/contest/1009/problem/D
题意,给你n、m两个数,n为图的点数,m为图的边数,G=(V,E)让你求满足下列条件的图G:①(u,v)€E ②gcd(u,v)=1;如果u和v之间没有边则gcd(u,v)是无关系的;
如果不能构成这样的图输出“Impossible”
如果能构成这样的图输出“Possible”;并输出图的边。
(1<=n,m<=1e5)
分析:方法一:其实我们可以直接枚举u,v两个点暴力求取gcd(u,v);看似是O(n^2logn)的复杂度,但实际情况却不是这样的,因为1是与2~n的数互质的,这样我们就有n-1条边了;
方法二:预处理欧拉函数(小于等于n且与n互质的数的个数);用欧拉函数还做。
PS:在比赛的时候想的是方法一,所以第二种就没写代码(懒);
悲剧的是忘记判断m<n-1,此时我们应该输出的是“Impossible”,因为n个点要构成图至少需要n-1条边,比赛的时候没注意这个疯狂WA 在第九组数据。orz。哎!~!
1 #include<cstdio> 2 #include<algorithm> 3 #include<math.h> 4 #include<queue> 5 #include<vector> 6 #include<set> 7 #include<iostream> 8 #include<cstring> 9 #include<bits/stdc++.h> 10 using namespace std; 11 #define ll long long 12 #define ull unsinged long long 13 #define mems(a,b) memset(a,b,sizeof(a)) 14 const int maxn=1e6+100; 15 int n,m; 16 pair<int,int>ans[maxn]; 17 ll gcd(ll a,ll b){ 18 if(b==0)return a; 19 return gcd(b,a%b); 20 } 21 22 23 int main() 24 { 25 scanf("%d%d",&n,&m); 26 if(m<n-1){ 27 cout<<"Impossible"<<endl; 28 return 0; 29 } 30 int cnt=0; 31 for(int v=1;v<=n;v++){ 32 if(cnt==m)break; 33 for(int u=v+1;u<=n;u++){ 34 if(gcd(u,v)==1){ 35 cnt++; 36 ans[cnt].first=v; 37 ans[cnt].second=u; 38 } 39 if(cnt==m)break; 40 } 41 } 42 if(cnt==m){ 43 cout<<"Possible"<<endl; 44 for(int i=1;i<=m;i++){ 45 cout<<ans[i].first<<" "<<ans[i].second<<endl; 46 } 47 } 48 else { 49 cout<<"Impossible"<<endl; 50 } 51 return 0; 52 }
E题链接:http://codeforces.com/contest/1009/problem/E
题意:起点为0终点为n,从起点到终点途中会有一些休息点,当你路过休息点之后你的旅游困难值就要从a1开始计算;例如:当n=7时,休息点为1和5那么旅游困难值为:3a1+2a2+a3+a4;当n=5时,休息点为2,则困难值为2a1+2a2+a3;
现在题目的要求是:他不知道有哪些休息点,考虑所有情况的话,可以有2^(n-1)种情况,休息点的选择概率是相同的。
现在要你求p*2^(n-1)的值为多少让它对mod=998244353去摸;p:的含义是困难值的均值。很显然p*2^(n-1)为正整数。
题解:
很容易就知道的是:P=∑(1,n) diffi求和;在乘以*2^(n-1)%mod;想得到上面的表达式就很简单。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 const int maxn=1e6+100; 5 const LL mod=998244353; 6 int n; 7 LL f[maxn]; 8 LL a[maxn]; 9 LL Q_Pow(LL a,LL n){ 10 LL cnt=1; 11 while(n){ 12 if(n&1) 13 cnt=cnt*a%mod; 14 a=a*a%mod; 15 n>>=1; 16 } 17 return cnt; 18 } 19 20 int main() 21 { 22 while(scanf("%d",&n)!=EOF){ 23 for(int i=1;i<=n;i++){ 24 scanf("%lld",&a[i]); 25 } 26 memset(f,0,sizeof(f)); 27 f[1]=a[1]; 28 LL sump=f[1]; 29 for(int i=2;i<=n;i++){ 30 LL dif=(a[i]-a[i-1]); 31 //cout<<"a[i]-a[i-1]="<<dif<<endl; 32 LL t1=Q_Pow(2,i-1); 33 //cout<<"2^(i-1)="<<t1<<endl; 34 f[i]=(f[i-1]+dif*Q_Pow(t1,mod-2)%mod)%mod; 35 sump=(f[i]+sump)%mod; 36 } 37 //cout<<"sump="<<sump<<endl; 38 cout<<sump*Q_Pow(2,n-1)%mod<<endl; 39 } 40 41 return 0; 42 }