Codeforces Round #359 (Div. 1)

A

http://codeforces.com/contest/685/standings

题意:给你n和m,找出(a,b)的对数,其中a满足要求:0<=a<n,a的7进制的位数和n-1的7进制的位数相同,b满足要求:0<=b<m,b的7进制的位数和m-1的7进制的位数相同,且a和b的7进制下的位上的数都不相同

思路:如果a b的位数和大于7显然会有重复,缩小范围以后,可以根据题意暴力枚举

 1 // #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <sstream>
 6 #include <string>
 7 #include <algorithm>
 8 #include <list>
 9 #include <map>
10 #include <vector>
11 #include <queue>
12 #include <stack>
13 #include <cmath>
14 #include <cstdlib>
15 // #include <conio.h>
16 using namespace std;
17 #define clc(a,b) memset(a,b,sizeof(a))
18 #define inf 0x3f3f3f3f
19 #define lson l,mid,rt<<1
20 #define rson mid+1,r,rt<<1|1
21 const int N=30;
22 const int M = 30010; 
23 const int MOD = 1e9+7;
24 #define LL long long
25 double const pi = acos(-1);
26 void fre() {
27     freopen("in.txt","r",stdin);
28 }
29 // inline int r() {
30 //     int x=0,f=1;char ch=getchar();
31 //     while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}
32 //     while(ch>='0'&&ch<='9') { x=x*10+ch-'0';ch=getchar();}return x*f;
33 // }
34 int dn,dm;
35 int digitt(int x){
36     if(x==0) return 1;
37     int ans=0;
38     while(x){
39          ans++;
40          x/=7;
41     }
42     return ans;
43 }
44 
45 int fun(int x,int d){
46      int s=0;
47      for(int i=1;i<=d;i++){
48          if(s&(1<<(x%7)))
49             return -1;
50          s|=(1<<(x%7));
51          x/=7;
52      }
53      return s;
54 }
55 void work(int n,int m){
56      int ans=0;
57      for(int i=0;i<=n;i++){
58          for(int j=0;j<=m;j++){
59              int tem1=fun(i,dn),tem2=fun(j,dm);
60              if(tem1!=-1&&tem2!=-1&&(tem1&tem2)==0){
61                 ans++;
62              }
63          }
64      }
65      printf("%d
",ans);
66 }
67 
68 int main(){
69     int n,m;
70     cin>>n>>m;
71     n--,m--;
72     dn=digitt(n);
73     dm=digitt(m);
74     if(dn+dm>7)
75         cout<<0<<endl;
76     else{
77          work(n,m);
78     }
79     return 0;
80 }
View Code

B

题意:找树的重心(删除该节点以后,最大子树的节点数小于等于原树的一半)

思路:预处理每个节点的数目,记录每个点的前驱,从最大子树的重心往上找该当前节点的重心(当前节点的重心一定在最大子树的重心和它的连线上)。并且重心唯一

 1 #include<iostream>
 2 #include<string>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<cstdio>
 6 #include<set>
 7 #include<map>
 8 #include<vector>
 9 #include<cstring>
10 #include<stack>
11 #include<cmath>
12 #include<queue>
13 #include <conio.h>
14 #define clc(a,b) memset(a,b,sizeof(a))
15 #include <bits/stdc++.h>
16 const int maxn = 20005;
17 const int inf=0x3f3f3f3f;
18 const double pi=acos(-1);
19 typedef long long LL;
20 using namespace std;
21 //const LL MOD = 1e9+7;
22 void fre(){freopen("in.txt","r",stdin);}
23 const int N = 300010;
24 int s[N],mx[N];
25 int ma[N];
26 int f[N];
27 vector<int> e[N];
28 
29 void dfs(int u){
30      s[u]=1;
31      for(int i=0;i<e[u].size();i++){
32          int v=e[u][i];
33          dfs(v);
34          s[u]+=s[v];
35          mx[u]=max(mx[u],s[v]);
36      }
37 }
38 
39 void dfs2(int u){
40      if(e[u].size()==0){
41          ma[u]=u;
42          return;
43      }
44      int x=0;
45      for(int i=0;i<e[u].size();i++){
46          int v=e[u][i];
47          dfs2(v);
48          if(s[x]<s[v])
49             x=v;
50      }
51     int y=ma[x];
52     while(1){
53              if(max(mx[y],s[u]-s[y])<=s[u]/2){
54                  ma[u]=y;
55                  break;
56              }
57              if(y==u)
58                 break;
59             y=f[y];
60          }
61 }
62 int main(){
63      int n,q;
64      cin>>n>>q;
65      for(int i=0;i<=n+1;i++)
66         e[i].clear();
67      for(int i=2;i<=n;i++){
68          int x;
69          cin>>x;
70          f[i]=x;
71          e[x].push_back(i);
72      }
73      dfs(1);
74      dfs2(1);
75      while(q--){
76          int x;
77          cin>>x;
78          printf("%d
",ma[x]);
79      }
80      return 0;
81 
82 }
View Code
原文地址:https://www.cnblogs.com/ITUPC/p/5632978.html