Codeforces Round #618 (div 1)做题记录
A.
从集合角度考虑式子的意义,就是选第一个数作为全集然后抠掉第二个数为1的位
连着做这个过程就是选一个数作为全集然后连着抠掉一些位
这样我们只要枚举第一个数就行了,前后缀加速一下这个过程
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,a[100005]; 4 int id,pre[100005],suf[100005],ans[100005]; 5 int main() 6 { 7 scanf("%d",&n); 8 for(int i=1;i<=n;++i)scanf("%d",&a[i]); 9 for(int i=1;i<=n;++i)pre[i]=pre[i-1]|a[i]; 10 for(int i=n;i>=1;--i)suf[i]=suf[i+1]|a[i]; 11 for(int i=1;i<=n;++i) 12 { 13 int x=pre[i-1]|suf[i+1]; 14 ans[i]=(a[i]|x)-x; 15 } 16 int id=1; 17 for(int i=1;i<=n;++i)if(ans[i]>ans[id])id=i; 18 swap(a[id],a[1]); 19 for(int i=1;i<=n;++i)printf("%d ",a[i]); 20 }
B.
只要判断是不是中心对称就行了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n; 4 struct Point 5 { 6 int x,y; 7 }a[100005]; 8 int main() 9 { 10 scanf("%d",&n); 11 for(int i=1;i<=n;++i)scanf("%d%d",&a[i].x,&a[i].y); 12 if(n&1) 13 { 14 puts("NO"); 15 return 0; 16 } 17 int X=a[1].x+a[n/2+1].x; 18 int Y=a[1].y+a[n/2+1].y; 19 bool yes=1; 20 for(int i=1;i<=n/2;++i)if(a[i].x+a[i+n/2].x!=X||a[i].y+a[i+n/2].y!=Y)yes=0; 21 if(yes)puts("YES"); 22 else puts("NO"); 23 }
C.
有一个简单的性质是从开头开始一定是一段一段连续段一样的
这种维护平均数连续段可以用单调栈来搞
每次新建一个点塞进去,然后和前面能合并就合并
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m; 4 double a[1000005],s[1000005]; 5 struct Node 6 { 7 int l,r; 8 double x; 9 Node(int L=0,int R=0){l=L;r=R;x=(s[r]-s[l-1])/(r-l+1);} 10 void maintain(){x=(s[r]-s[l-1])/(r-l+1);} 11 }; 12 Node q[1000005]; 13 int main() 14 { 15 scanf("%d",&n); 16 for(int x,i=1;i<=n;++i) 17 { 18 scanf("%d",&x); 19 a[i]=x; 20 s[i]=s[i-1]+x; 21 } 22 for(int i=1;i<=n;++i) 23 { 24 q[++m]=Node(i,i); 25 while(m>1&&q[m].x<q[m-1].x) 26 { 27 q[m-1].r=q[m].r; 28 m--; 29 q[m].maintain(); 30 } 31 } 32 for(int i=1;i<=m;++i) 33 { 34 for(int j=q[i].l;j<=q[i].r;++j)printf("%.10f\n",q[i].x); 35 } 36 }