codeforces #294 div2 only
2015-03-01 00:23:47
总结:A,B,C水题,D题翔提示哒,E题是个LCA加分类讨论,比赛中没敲完。。。
比赛搞了4题,赛后补了E。小结一下...(Orz Jay巨一小时AK...)
A:暴力,注意Knight的符号是'n'(Jay巨这里逗比辣..)
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <string> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 15 #define MEM(a,b) memset(a,b,sizeof(a)) 16 #define REP(i,n) for(int i=1;i<=(n);++i) 17 #define REV(i,n) for(int i=(n);i>=1;--i) 18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i) 20 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 21 #define MP(a,b) make_pair(a,b) 22 23 typedef long long ll; 24 typedef pair<int,int> pii; 25 const int INF = (1 << 30) - 1; 26 27 char g[10][10]; 28 29 int main(){ 30 for(int i = 0; i < 8; ++i) 31 scanf("%s",g[i]); 32 int a1 = 0,a2 = 0; 33 for(int i = 0; i < 8; ++i){ 34 for(int j = 0; j < 8; ++j){ 35 char c = g[i][j]; 36 if(c == 'Q') a1 += 9; 37 else if(c == 'R') a1 += 5; 38 else if(c == 'B' || c == 'N') a1 += 3; 39 else if(c == 'P') a1 += 1; 40 else if(c == 'q') a2 += 9; 41 else if(c == 'r') a2 += 5; 42 else if(c == 'b' || c == 'n') a2 += 3; 43 else if(c == 'p') a2 += 1; 44 } 45 } 46 if(a1 == a2) printf("Draw\n"); 47 else if(a1 > a2) printf("White\n"); 48 else printf("Black\n"); 49 return 0; 50 }
B:暴力,排序。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <string> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 15 #define MEM(a,b) memset(a,b,sizeof(a)) 16 #define REP(i,n) for(int i=1;i<=(n);++i) 17 #define REV(i,n) for(int i=(n);i>=1;--i) 18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i) 20 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 21 #define MP(a,b) make_pair(a,b) 22 23 typedef long long ll; 24 typedef pair<int,int> pii; 25 const int INF = (1 << 30) - 1; 26 27 int n; 28 int a[100010],b[100010],c[100010]; 29 30 int main(){ 31 scanf("%d",&n); 32 REP(i,n) scanf("%d",a + i); 33 REP(i,n - 1) scanf("%d",b + i); 34 REP(i,n - 2) scanf("%d",c + i); 35 sort(a + 1,a + n + 1); 36 sort(b + 1,b + n); 37 sort(c + 1,c + n - 1); 38 REP(i,n) if(a[i] != b[i]){ 39 printf("%d\n",a[i]); 40 break; 41 } 42 REP(i,n - 1) if(b[i] != c[i]){ 43 printf("%d\n",b[i]); 44 break; 45 } 46 return 0; 47 }
C:暴力扫,找答案即可。用公式min(a,b,(a+b)/3))也行。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <string> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 15 #define MEM(a,b) memset(a,b,sizeof(a)) 16 #define REP(i,n) for(int i=1;i<=(n);++i) 17 #define REV(i,n) for(int i=(n);i>=1;--i) 18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i) 20 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 21 #define MP(a,b) make_pair(a,b) 22 23 typedef long long ll; 24 typedef pair<int,int> pii; 25 const int INF = (1 << 30) - 1; 26 27 int n,m; 28 29 int main(){ 30 scanf("%d%d",&n,&m); 31 int ans = 0; 32 for(int i = 0; i <= m; ++i){ 33 int tn = n - 2 * i; 34 if(tn < 0) break; 35 int tm = m - i; 36 ans = max(ans,i + min(tn,tm / 2)); 37 } 38 printf("%d\n",ans); 39 return 0; 40 }
D:维护前缀和,用map[i][j]表示以i字符结尾,前缀和为j的情况数。具体代码可见。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <string> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 15 #define MEM(a,b) memset(a,b,sizeof(a)) 16 #define REP(i,n) for(int i=1;i<=(n);++i) 17 #define REV(i,n) for(int i=(n);i>=1;--i) 18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i) 20 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 21 #define MP(a,b) make_pair(a,b) 22 23 typedef long long ll; 24 typedef pair<int,int> pii; 25 const int INF = (1 << 30) - 1; 26 27 int v[30]; 28 map<ll,int> mp[30]; 29 char s[100010]; 30 31 int main(){ 32 for(int i = 0; i < 26; ++i) scanf("%d",v + i); 33 ll ans = 0,sum = 0; 34 scanf("%s",s + 1); 35 int len = strlen(s + 1); 36 REP(i,len){ 37 int id = s[i] - 'a'; 38 ans += mp[id][sum]; 39 sum += v[id]; 40 mp[id][sum]++; 41 } 42 printf("%I64d\n",ans); 43 return 0; 44 }
E:求出树中距离两点距离相等的点的个数。首先倍增求两个点a,b的lca,然后分3类讨论。
(1)lca == a 或者 lca == b,求出a,b的中点,如果没有中点答案是0,否则从中点延伸出去的子树都符合。
(2)lca != a ,lca != b,且a到lca的距离等于b到lca的距离.....
(3)lca != a, lca != b,且a到lca的距离不等于b到lca的距离.....
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <string> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 15 #define MEM(a,b) memset(a,b,sizeof(a)) 16 #define REP(i,n) for(int i=1;i<=(n);++i) 17 #define REV(i,n) for(int i=(n);i>=1;--i) 18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i) 20 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 21 #define MP(a,b) make_pair(a,b) 22 23 typedef long long ll; 24 typedef pair<int,int> pii; 25 const int INF = (1 << 30) - 1; 26 const int MAXN = 100010; 27 const int MAX_LOG = 20; 28 29 int n,m; 30 int first[MAXN],ecnt; 31 int fa[MAX_LOG][MAXN],dep[MAXN]; 32 int dis[MAXN],sz[MAXN]; 33 34 struct edge{ 35 int v,next; 36 }e[MAXN << 1]; 37 38 void Init(){ 39 MEM(first,-1); 40 ecnt = 0; 41 } 42 43 void Add_edge(int u,int v){ 44 e[++ecnt].next = first[u]; 45 e[ecnt].v = v; 46 first[u] = ecnt; 47 } 48 49 void Dfs(int p,int pre,int d){ 50 fa[0][p] = pre; 51 dep[p] = d; 52 sz[p] = 1; 53 for(int i = first[p]; ~i; i = e[i].next){ 54 int v = e[i].v; 55 if(v == pre) continue; 56 Dfs(v,p,d + 1); 57 sz[p] += sz[v]; 58 } 59 } 60 61 void Pre(){ 62 Dfs(1,-1,0); 63 for(int k = 0; k + 1 < MAX_LOG; ++k){ 64 for(int v = 1; v <= n; ++v){ 65 if(fa[k][v] < 0) fa[k + 1][v] = -1; 66 else fa[k + 1][v] = fa[k][fa[k][v]]; 67 } 68 } 69 } 70 71 int Lca(int u,int v){ 72 if(dep[u] > dep[v]) swap(u,v); 73 for(int k = MAX_LOG - 1; k >= 0; --k){ 74 if((dep[v] - dep[u]) & (1 << k)) 75 v = fa[k][v]; 76 } 77 if(u == v) return u; 78 for(int k = MAX_LOG - 1; k >= 0; --k){ 79 if(fa[k][u] != fa[k][v]){ 80 u = fa[k][u]; 81 v = fa[k][v]; 82 } 83 } 84 return fa[0][u]; 85 } 86 87 int Up(int d,int u){ 88 for(int k = MAX_LOG - 1; k >= 0; --k){ 89 if(d & (1 << k)) 90 u = fa[k][u]; 91 } 92 return u; 93 } 94 95 int Solve(int a,int b){ 96 int lca = Lca(a,b); 97 //printf("lca : %d\n",lca); 98 if(lca == a || lca == b){ 99 int d = abs(dep[a] - dep[b]); 100 if(dep[a] > dep[b]) swap(a,b); 101 if(d % 2 == 0){ 102 d /= 2; 103 b = Up(d - 1,b); 104 int bf = fa[0][b]; 105 return sz[bf] - sz[b]; 106 } 107 else return 0; 108 } 109 else{ 110 int d = dep[a] - dep[lca] + dep[b] - dep[lca]; 111 if(d % 2 == 0){ 112 d /= 2; 113 if(dep[a] - dep[lca] == dep[b] - dep[lca]) 114 return n - sz[Up(d - 1,a)] - sz[Up(d - 1,b)]; 115 else{ 116 if(dep[a] > dep[b]) swap(a,b); 117 b = Up(d - 1,b); 118 int bf = fa[0][b]; 119 return sz[bf] - sz[b]; 120 } 121 } 122 else return 0; 123 } 124 } 125 126 int main(){ 127 Init(); 128 int a,b; 129 scanf("%d",&n); 130 REP(i,n - 1){ 131 scanf("%d%d",&a,&b); 132 Add_edge(a,b); 133 Add_edge(b,a); 134 } 135 Pre(); 136 scanf("%d",&m); 137 REP(i,m){ 138 scanf("%d%d",&a,&b); 139 if(a == b) printf("%d\n",n); 140 else printf("%d\n",Solve(a,b)); 141 } 142 return 0; 143 }