Codeforces Round #496 (Div. 3)

Posted hdujackyan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #496 (Div. 3)相关的知识,希望对你有一定的参考价值。

1.(1005E2)http://codeforces.com/contest/1005/problem/E2

题意:给定一个长度为n的排列,先求有多少个区间[l,r]满足该区间的中位数为m

分析:设置函数count(m):表示对于给定长度为n的序列,有多少个区间的中位数是>=m的(当【区间>=m数的个数】>【区间<m的个数】时满足).最终的答案为count(m)-count(m+1)。

那么如何求解count(m)?设置变量cnt表示当前累计的值,初始值为n,当a[i]>=m时,cnt++;当a[i]<m时,cnt--。从头开始枚举区间的右端点[1,i],并计算cnt(1,i),每次只需要找出前面有多少个j满足cnt(1,j)<cnt(1,i)即可。设置sum[x]表示cnt=x的个数有多少。

那么如何求解前面有多少个数小于cnt(1,i)呢?设置变量add,表示满足cnt(1,j)<cnt(1,i-1)的数有多少。每次枚举第i位时,若a[i]>=m,则先add+=sum[cnt],cnt++。否则cnt--,add-=sum[cnt](有点类似于莫队算法中一步步更新)。每次访问一个i时,最后的答案result+=add。

参考:http://www.cnblogs.com/widsom/p/9290269.html

技术分享图片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=2e5+10;
 7 int a[maxn],sum[2*maxn],n;
 8 
 9 ll count(int m)
10 {
11     memset(sum,0,sizeof(sum));
12     int cnt=n;
13     sum[n]=1;
14     ll add=0,result=0;
15     for ( int i=1;i<=n;i++ )
16     {
17         if ( a[i]>=m ) 
18         {
19             add+=sum[cnt];
20             cnt++;
21         }
22         else
23         {
24             cnt--;
25             add-=sum[cnt];
26         }
27         sum[cnt]++;
28         result+=add;
29     }
30     return result;
31 }
32 
33 int main()
34 {
35     int m,i,j,k,x,y,z;
36     ll ans;
37     while ( scanf("%d%d",&n,&m)!=EOF )
38     {
39         for ( i=1;i<=n;i++ ) scanf("%d",&a[i]);
40         ans=count(m)-count(m+1);
41         printf("%lld
",ans);
42     }
43     return 0;
44 }
1005E2

 

2.(1005F)http://codeforces.com/contest/1005/problem/F

题意:有n个点和m条无向边,求至多k种挑选n-1边的方案,满足根(编号为1的点)到所有点的距离之和最小,输出方案个数

分析:设置b[i]表示点i到根的最短距离(通过bfs)实现。然后对于一个点u来说考虑所有的边(u,v),若满足d[u]==d[v]+1,那么该边最终是可以选择的,设置G[u]表示u点的前驱的边中有哪些是可以选择的。设置f[i]表示对于点i当前选择第G[i][f[i]]条边,所有的f[i]初始化为0。所有对于编号为[2,n],每次挑选前驱中的一条边,最后组成的无向图是一定满足条件的。

那么如何挑选出k种方案呢?思路大致同数字中的进位(个位满10,十位加1;十位满10,百位+1。以此类推),此处也一样,f[i]==G[i].size(),f[i]==0,f[i+1]++.直到最后不能加为止

参考:http://codeforces.com/blog/entry/60511

技术分享图片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<queue>
 6 #include<string>
 7 #include<iostream>
 8 using namespace std;
 9 const int maxn=2e5+10;
10 const int inf=1e9;
11 vector<int>E[maxn],G[maxn];
12 vector<string>ans;
13 int a[maxn],b[maxn],f[maxn],d[maxn],n;
14 
15 void BFS()
16 {
17     for ( int i=1;i<=n;i++ ) d[i]=inf;
18     d[1]=0;
19     queue<int>que;
20     que.push(1);
21     while ( !que.empty() )
22     {
23         int u=que.front();
24         que.pop();
25         for ( int i=0;i<E[u].size();i++ )
26         {
27             int v=E[u][i];
28             if ( d[v]==inf )
29             {
30                 d[v]=d[u]+1;
31                 que.push(v);
32             }
33         }
34     }
35 }
36 
37 int main()
38 {
39     int m,k,i,j,x,y,z,u,v,cnt;
40     while ( scanf("%d%d%d",&n,&m,&k)!=EOF )
41     {
42         ans.clear();
43         for ( i=1;i<=n;i++ )
44         {
45             E[i].clear();
46             G[i].clear();
47         }
48         for ( i=1;i<=m;i++ ) 
49         {
50             scanf("%d%d",&a[i],&b[i]);
51             E[a[i]].push_back(b[i]);
52             E[b[i]].push_back(a[i]);
53         }
54         BFS();
55         for ( i=1;i<=m;i++ )
56         {
57             u=a[i],v=b[i];
58             if ( d[u]==d[v]+1 ) G[u].push_back(i);
59             if ( d[v]==d[u]+1 ) G[v].push_back(i);
60         }
61         memset(f,0,sizeof(f));
62         cnt=0;
63         for ( j=1;j<=k;j++ )
64         {
65             string s(m,0);
66             for ( i=2;i<=n;i++ )
67             {
68                 s[G[i][f[i]]-1]=1;
69             }
70             ans.push_back(s);
71             bool ok=false;
72             for ( i=2;i<=n;i++ )
73             {
74                 if ( f[i]+1<G[i].size() )
75                 {
76                     ok=true;
77                     f[i]++;
78                     break;
79                 }
80                 else f[i]=0;
81             }
82             if ( !ok ) break;
83         }
84         cout<<ans.size()<<endl;
85         for ( i=0;i<ans.size();i++ ) cout<<ans[i]<<endl;
86     }
87     return 0;
88 }
1005F

 

以上是关于Codeforces Round #496 (Div. 3)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #496 (Div. 3)未完结

Codeforces Round #496 (Div. 3)

Codeforces Round #496 (Div. 3) ABCDE1

Codeforces Round #496 (Div. 3)A~F

CodeForces -Codeforces Round #496 (Div. 3) E2. Median on Segments (General Case Edition)

Codeforces Round #283 (Div. 2)CDE题解