Codeforces Global Round 1 做题记录

A.

题解:快速幂

代码:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define maxn 100005
 4 using namespace std;
 5 const ll mod=2;
 6 ll b,k;
 7 ll a[maxn];
 8 ll fastpow(ll a,ll p)
 9 {
10     ll ans=1;
11     while(p)
12     {
13         if(p&1)ans=ans*a%mod;
14         a=a*a%mod;p>>=1;
15     }
16     return ans;
17 }
18 int main()
19 {
20     scanf("%I64d%I64d",&b,&k);
21     for(int i=1;i<=k;++i)scanf("%I64d",&a[i]);
22     ll n=0;
23     for(int i=1;i<=k;++i)n=(n+a[i]*fastpow(b,k-i)%mod)%mod;
24     if(n)puts("odd");
25     else puts("even");
26 }
View Code

B.

题解:考虑两两相邻点之间的距离,贪心取最小的k-1个

 1 #include<bits/stdc++.h>
 2 #define maxn 100005
 3 using namespace std;
 4 int n,m,k;
 5 int a[maxn];
 6 priority_queue<int,vector<int>,greater<int> >q;
 7 int main()
 8 {
 9     scanf("%d%d%d",&n,&m,&k);
10     int ans=n;
11     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
12     k=n-k;
13     for(int i=1;i<n;++i)q.push(a[i+1]-a[i]-1);
14     while(k--)
15     {
16         int t=q.top();
17         q.pop();
18         ans+=t;
19     }
20     printf("%d\n",ans);
21     return 0;
22 }
View Code

C.

题解:找规律,除了2^k-1以外其他情况ans=2^p-1(其中p为满足ans>a的最小的数),2^k-1的情况打表就行

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int q;
 4 int vis[]={0,0,1,1,5,1,21,1,85,73,341,89,1365,1,5461,4681,21845,1,87381,1,349525,299593,1398101,178481,5592405,1082401};
 5 int main()
 6 {
 7     scanf("%d",&q);
 8     while(q--)
 9     {
10         int a;
11         scanf("%d",&a);
12         int p=1;
13         while(((1<<p)-1)<a)p++;
14         if(a==((1<<p)-1))
15         {
16             if(!vis[p])
17             {
18                 int ans=0;
19                 for(int b=1;b<a;++b)ans=max(ans,__gcd(a^b,a&b));
20                 vis[p]=ans;
21                 printf("%d\n",ans);
22             }
23             else printf("%d\n",vis[p]);
24         }
25         else printf("%d\n",(1<<p)-1);
26     }
27     return 0;
28 }
View Code

D.

题解:考虑3个三元组[ i-1 ,i ,i+1 ]可以被拆成[ i-1, i-1, i-1 ] , [ i , i , i ] , [ i+1, i+1, i+1 ],所以每个状态中这样的三元组不会超过2个

然后dp(i,j,k)表示有j个[ i-1 ,i ,i+1 ] , k个[ i , i+1 , i+2 ],转移每次枚举一个 l ,表示dp(i+1,k,l),其中多l个[ i+1 , i+2, i+3 ]

那相同的三元组怎么处理?( num(i) - j -k -l )/3 个,直接加上就好了

 1 #include<bits/stdc++.h>
 2 #define inf 1000000000
 3 #define maxn 1000005
 4 using namespace std;
 5 int n,m;
 6 int has[maxn];
 7 int dp[maxn][3][3];
 8 int main()
 9 {
10     scanf("%d%d",&n,&m);
11     for(int x,i=1;i<=n;++i)
12     {
13         scanf("%d",&x);
14         has[x]++;
15     }
16     for(int i=0;i<=m;++i)
17     {
18         for(int j=0;j<=2;++j)
19         {
20             for(int k=0;k<=2;++k)dp[i][j][k]=-inf;
21         }
22     }
23     dp[0][0][0]=0;
24     for(int i=0;i<m;++i)
25     {
26         for(int j=0;j<=min(has[i],2);++j)
27         {
28             for(int k=0;k<=min(has[i+1],2);++k)
29             {
30                 for(int l=0;l<=min(has[i+2],2);++l)if(has[i+1]>=j+k+l)
31                 {
32                     dp[i+1][k][l]=max(dp[i+1][k][l],dp[i][j][k]+l+(has[i+1]-j-k-l)/3);
33                 }
34             }
35         }
36     }
37     printf("%d\n",dp[m][0][0]);
38     return 0;
39 }
View Code

E.

题解:原题,以前有一道前缀和类似的结论

考虑每次操作,本质上是在差分数组中交换两个数的位置

我们只需要判断差分数组是否同构以及原数组首尾是否相同就行了

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define maxn 100005
 4 using namespace std;
 5 int n;
 6 ll c[maxn],t[maxn],x[maxn],y[maxn]; 
 7 int main()
 8 {
 9     scanf("%d",&n);
10     for(int i=1;i<=n;++i)scanf("%I64d",&c[i]);
11     for(int i=1;i<=n;++i)scanf("%I64d",&t[i]);
12     if(c[1]!=t[1]||c[n]!=t[n])
13     {
14         puts("No");
15         return 0;
16     }
17     else
18     {
19         for(int i=2;i<=n;++i)x[i]=c[i]-c[i-1];
20         for(int i=2;i<=n;++i)y[i]=t[i]-t[i-1];
21         sort(x+1,x+n+1);
22         sort(y+1,y+n+1);
23         bool yes=1;
24         for(int i=1;i<=n;++i)if(x[i]!=y[i])yes=0;
25         if(yes)puts("Yes");
26         else puts("No");
27     }
28     return 0; 
29 }
View Code

F,G,H留坑

猜你喜欢

转载自www.cnblogs.com/uuzlove/p/10358689.html