Codeforces Global Round 1 做題記錄
阿新 • • 發佈:2019-02-10
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>>=1View Code; 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 }
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(intView Codei=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 }
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 做題記錄