1. 程式人生 > >Codeforces Global Round 1 做題記錄

Codeforces Global Round 1 做題記錄

bit 題解 tor a* 除了 相同 while vector -a

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留坑

Codeforces Global Round 1 做題記錄