Codeforces Round #250 (Div. 1)
这几次CF都挺惨。。
A
没条边权设为两端点的最小点权,最后加起来。
数组开小,WA一次
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 2010 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 int v[N]; 18 int a[N]; 19 int main() 20 { 21 int i,j,n,m; 22 cin>>n>>m; 23 for(i = 1; i <= n; i++) 24 scanf("%d",&v[i]); 25 for(i = 1; i <= m ;i++) 26 { 27 int x,y; 28 scanf("%d%d",&x,&y); 29 a[i] = min(v[x],v[y]); 30 } 31 int ans = 0; 32 for(i = 1 ;i <= m ;i++) 33 { 34 ans+=a[i]; 35 } 36 cout<<ans<<endl; 37 return 0; 38 }
B
以点权排序,删除某个点之后,哪些比它点权大的不再连通就说明那些点对的p值肯定为他的点权,想到了这点,却忘了并差集可以使不连通块连通。
做法:给每个边一个边权,为两端点的最小点权,以边权从大到小排序,依次进行合并,若当前不连通这以这个边权*块1的数量*块2的数量
排序的时候 错把m写成n wa一次。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 100010 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 int fa[N],res[N],a[N]; 18 int find(int x) 19 { 20 if(fa[x]!=x) 21 { 22 fa[x] = find(fa[x]); 23 return fa[x]; 24 } 25 return x; 26 } 27 struct node 28 { 29 int u,v,w; 30 }p[N]; 31 bool cmp(node a,node b) 32 { 33 return a.w>b.w; 34 } 35 int main() 36 { 37 int n,m,i; 38 cin>>n>>m; 39 for(i = 1; i <=n; i++) 40 { 41 scanf("%d",&a[i]); 42 fa[i] = i; 43 res[i] = 1; 44 } 45 for(i =1 ;i <=m ;i++) 46 { 47 scanf("%d%d",&p[i].u,&p[i].v); 48 p[i].w = min(a[p[i].u],a[p[i].v]); 49 } 50 sort(p+1,p+m+1,cmp); 51 double ans = 0; 52 for(i = 1; i <= m ;i++) 53 { 54 int tx = find(p[i].u),ty = find(p[i].v); 55 if(tx!=ty) 56 { 57 fa[tx] = ty; 58 ans+=(double)p[i].w*res[tx]*res[ty]; 59 res[ty]+=res[tx]; 60 // res[tx] = 0; 61 } 62 } 63 printf("%.6f\n",(ans*2)/(n*1.0*(n-1))); 64 return 0; 65 }
D
没有比这题更悲伤了,最后20分钟看,十几分钟敲完,最后十几秒交上,wa了,,发现少写了个lm。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 100010 12 #define LL __int64 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 LL s[N<<2],lm[N<<2]; 18 int a[N]; 19 void up(int w) 20 { 21 s[w] = s[w<<1]+s[w<<1|1]; 22 lm[w] = max(lm[w<<1],lm[w<<1|1]); 23 } 24 void build(int l,int r,int w) 25 { 26 if(l==r) 27 { 28 s[w] = a[l]; 29 lm[w] = a[l]; 30 return ; 31 } 32 int m = (l+r)>>1; 33 build(l,m,w<<1); 34 build(m+1,r,w<<1|1); 35 up(w); 36 } 37 LL query(int a,int b,int l,int r,int w) 38 { 39 if(a<=l&&b>=r) 40 { 41 return s[w]; 42 } 43 int m = (l+r)>>1; 44 LL res=0; 45 if(a<=m) res+=query(a,b,l,m,w<<1); 46 if(b>m) res+=query(a,b,m+1,r,w<<1|1); 47 return res; 48 } 49 void update(int p,int d,int l,int r,int w) 50 { 51 if(l==r) 52 { 53 s[w] = lm[w] = d; 54 return ; 55 } 56 int m = (l+r)>>1; 57 if(p<=m) update(p,d,l,m,w<<1); 58 else update(p,d,m+1,r,w<<1|1); 59 up(w); 60 } 61 void find(int a,int b,int mod,int l,int r,int w) 62 { 63 if(a<=l&&b>=r) 64 { 65 if(lm[w] < mod) 66 return ; 67 if(l==r) 68 { 69 int k = s[w]%mod; 70 s[w] = lm[w] = k; 71 return ; 72 } 73 int m = (l+r)>>1; 74 find(a,b,mod,l,m,w<<1); 75 find(a,b,mod,m+1,r,w<<1|1); 76 up(w); 77 return ; 78 } 79 int m = (l+r)>>1; 80 if(a<=m) find(a,b,mod,l,m,w<<1); 81 if(b>m) find(a,b,mod,m+1,r,w<<1|1); 82 up(w); 83 } 84 int main() 85 { 86 int n,m,i; 87 cin>>n>>m; 88 for(i = 1; i <=n; i++) 89 scanf("%d",&a[i]); 90 build(1,n,1); 91 int l,r,x,k; 92 while(m--) 93 { 94 scanf("%d",&k); 95 if(k==1) 96 { 97 scanf("%d%d",&l,&r); 98 LL k = query(l,r,1,n,1); 99 printf("%I64d\n",k); 100 } 101 else if(k==2) 102 { 103 scanf("%d%d%d",&l,&r,&x); 104 find(l,r,x,1,n,1); 105 } 106 else 107 { 108 scanf("%d%d",&k,&x); 109 update(k,x,1,n,1); 110 } 111 } 112 return 0; 113 }
小小总结下:貌似每题都有注意不到的地方,还各不相同,说明不是我记忆力的问题,是注意力的问题,有空多刷几场TC,我印象中TC没有不出问题的时候,所以我现在依旧安稳的呆在DIV2。
发现学的多就会想得多,B题一直想在强连通分量上,心里觉得图的东西不是特别会,隐隐约约的觉得应该做不出来了,可又发现过的人好多,应该是会的,比赛的时候想的太多了,思路没有前行在正确的方向,注意力不能完全集中在题上。