Codeforces Round #196 (Div. 2)
A
题意:O(-1)
思路:排个序搞定。
B
题意:O(-1)
思路:坑了我好久,这个框框水平垂直比例固定,分两种情况即可,不能旋转,我想多了,分了四种情况。
C
题意:一列n个位置,让你填m个数,当连续数达到k时,分数乘以2,计数清零,当不连续时,计数也清零,没到达k之前分数+1.
思路:很显然的问题是让我们处理填m个位置,并且使连续的k个数次数最少。我们先让m个数k-1每次填,填一次空一位,直到不够填了就往前面的空位填。设连续k个次数为mm,那么就是(((2*k)+k)*2……+k)*2,等比数列求和之后为k*(2^mm-2),不连续k的值为m-mm*k。注意要注意了细节很多,WA了两次。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 7 typedef long long lld; 8 const lld mod=1000000009; 9 10 lld Pow(lld a, int b) 11 { 12 lld ans=1; 13 while(b) 14 { 15 if(b&1) ans=(ans*a)%mod; 16 b>>=1; 17 a=(a*a)%mod; 18 } 19 return ans%mod; 20 } 21 22 int main() 23 { 24 lld n, m, k; 25 while(cin >> n >> m >> k) 26 { 27 lld c1, c2, s1, num, mm, ans=0; 28 c1=n/k, s1=n%k; 29 c2=m/(k-1); 30 num=min(c1,c2); 31 if(c1>c2) s1+=k*(c1-c2); 32 mm=m-num*(k-1); 33 mm-=min(mm,s1); 34 if(mm) ans=(k*((Pow(2,mm+1)-2+mod)%mod))%mod; 35 ans=(ans+m-k*mm%mod+mod)%mod; 36 cout << ans <<endl; 37 } 38 } 39 /* 40 23888888 508125 3 41 */
D
题意:有一颗n个节点的树,树中有m个恶魔,然后给你一个控制距离d,问你树中哪些节点能控制住所有恶魔(离最远恶魔距离小于等于d)。
思路:很显然的树形dp,开始没考虑清楚一点,把所有节点的最长半径以及次长半径都初始化为0,这样会存在一个小bug,因为当有一个恶魔节点存在树中(此时此节点最长半径为0),父亲节点的最长半径为此节点更新上去的,传递下来的时候此节点只能利用父亲节点的次长半径,当次长半径初始化为0时,此时更新此节点的话次长半径就要大于最长半径,所以节点最长半径和次长半径初始化为-oo,有恶魔的节点最长半径改为0即可,开始没考虑到这点。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 #include <queue> 7 using namespace std; 8 9 const int maxn=100005; 10 const int oo=0x3fffffff; 11 int fmax[maxn], smax[maxn], color[maxn], f[maxn]; 12 vector<int>vt[maxn]; 13 int n, m, d; 14 15 void init() 16 { 17 for(int i=0; i<=n; i++) 18 { 19 vt[i].clear(); 20 fmax[i]=smax[i]=-oo; 21 color[i]=f[i]=0; 22 } 23 } 24 25 void dfs(int u, int fa) 26 { 27 for(int i=0; i<vt[u].size(); i++) 28 { 29 int v=vt[u][i]; 30 if(v==fa) continue; 31 dfs(v,u); 32 if(color[v]) 33 { 34 color[u]++; 35 if(fmax[v]+1>fmax[u]) smax[u]=fmax[u], fmax[u]=fmax[v]+1; 36 else if(fmax[v]+1>smax[u]) smax[u]=fmax[v]+1; 37 } 38 } 39 } 40 41 void DFS(int u, int fa) 42 { 43 if(u==1) ; 44 else 45 { 46 if(fmax[fa]-1==fmax[u]) 47 { 48 if(smax[fa]+1>fmax[u]) smax[u]=fmax[u], fmax[u]=smax[fa]+1; 49 else if(smax[fa]+1>smax[u]) smax[u]=smax[fa]+1; 50 } 51 else 52 { 53 if(fmax[fa]+1>fmax[u]) smax[u]=fmax[u], fmax[u]=fmax[fa]+1; 54 else if(fmax[fa]+1>smax[u]) smax[u]=fmax[fa]+1; 55 } 56 } 57 for(int i=0; i<vt[u].size(); i++) 58 if(vt[u][i]!=fa)DFS(vt[u][i],u); 59 } 60 61 int bfs(int st) 62 { 63 int ans=0; 64 queue<int>q; 65 q.push(st); 66 while(!q.empty()) 67 { 68 int u=q.front(); 69 q.pop(); 70 if(fmax[u]<=d) ans++; 71 for(int i=0; i<vt[u].size(); i++) 72 { 73 int v=vt[u][i]; 74 if(v==f[u]) continue; 75 f[v]=u; 76 q.push(v); 77 } 78 } 79 return ans; 80 } 81 82 int main() 83 { 84 while(cin >> n >> m >> d) 85 { 86 init(); 87 int u, v; 88 for(int i=1; i<=m; i++) 89 { 90 scanf("%d",&u); 91 color[u]=1; 92 fmax[u]=0; 93 } 94 for(int i=1; i<n; i++) 95 { 96 scanf("%d%d",&u,&v); 97 vt[u].push_back(v); 98 vt[v].push_back(u); 99 } 100 dfs(1,0); 101 DFS(1,0); 102 int ans=bfs(1); 103 cout << ans <<endl; 104 } 105 return 0; 106 } 107 /* 108 10 1 0 109 3 110 10 1 111 9 4 112 4 5 113 6 4 114 2 4 115 7 5 116 8 3 117 5 3 118 1 3 119 120 1 121 */