公司网站表达的内容,什么网站权重快,优秀的网站有哪些,支付的网站建设费整么做账#xff08;持续更新中…………#xff09; 去八十中被屠成渣了#xff0c;被屠得毫无还手之力#xff0c;被屠得丧心病狂#xff0c;停都停不下来#xff0c;于是只好来写写题解了。 题目在openjudge上都有#xff0c;自己去翻。 Day 1#xff1a; 第一题#xff1a;…持续更新中………… 去八十中被屠成渣了被屠得毫无还手之力被屠得丧心病狂停都停不下来于是只好来写写题解了。 题目在openjudge上都有自己去翻。 Day 1 第一题 这道概率题囧翻了…………卡精度……………… 我们考虑我们枚举其中一个被解决的时候另外一个还剩多少体力那么两个人收到伤害的次数都是固定的假设第一个人被打了n次第二个人被打了m次那么就相当于将这m次不断插入到这n次之间的空去不能插到第n次之后的空里面去那么这就是个简单的组合计数了。 关于精度问题…………这个有点囧…………我们考虑第二个人的第m次可以由前一次推出来然后将一些可能会导致精度下降的运算放到后面去做…………就差不多了吧………… View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includecmath5 6 using namespace std;7 8 const int maxn20010;9 const double eps1e-8;
10
11 int n;
12
13 double p;
14
15 long double solve(int n,long double p)
16 {
17 long double ansn,tmp1;
18 for (int a1;an;a)
19 {
20 tmp*p*(na)/a*(1-p);
21 ansans*ptmp*(n-a);
22 }
23 return ans*p;
24 }
25
26 int main()
27 {
28 int t0;
29 while (~scanf(%d%lf,n,p))
30 {
31 t;
32 printf(Case %d: %.2lf\n,t,(double)(solve(n,p)solve(n,1-p)));
33 }
34
35 return 0;
36 } 第二题 我一开始拿hash裸的…………其他人拿kmp裸的好像都比我裸的少了10分…………囧………… 我们考虑这个问题的本质吧如果我们倒着做就相当于询问前缀能否拆为若干子串使得每一个都是选出的后缀的一个前缀。这样感觉好囧的样子于是我们换个方向。假设我们从前往后做来构造这个后缀那么我们处理到某个位置时相当于是构造出了这个目标后缀的一个前缀我们考虑如何构造这个前缀。我们先对整个串做一次KMP然后从前往后走。假设我们这时走到了一个位置p我们已经得到了一个前缀s然后考虑我们构造新串。如果我们发现当前串无法与已构造出的前缀进行任何一位的匹配那么我们这个时候如果想要得到一个合法的串就只有把以后造出的前缀与当前这个串进行拼接形成新的前缀否则如果能够匹配的话则代表当前串能够与原前缀进行匹配则说明当前前缀合法。我们考虑我们如何检验这两个串是否能够匹配这个可以用KMP做。考虑到我们要修改这个前缀那么解决的办法就是每次对这个前缀暴力KMP因为考虑到每个字符最多只被重做一次所以依然是O(n)的。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 5 using namespace std;6 7 const int maxn1000010;8 9 int n,fail[maxn];
10
11 char s[maxn];
12
13 int main()
14 {
15 int t;
16 scanf(%d,t);
17 for (int p1;pt;p)
18 {
19 scanf(%s,s);
20 nstrlen(s);
21 fail[0]0;
22 int b0,last1,lastl1,nowp0;
23 for (int a1;an;a)
24 {
25 while (b s[nowpb]!s[a])
26 bfail[b-1];
27 if (s[nowpb]s[a]) b;
28 if (!b)
29 {
30 nowplast-lastl;
31 int nowla-nowp1;
32 for (int clastl;cnowl;c)
33 {
34 int dfail[c-1];
35 while (d s[nowpd]!s[pc])
36 dfail[d-1];
37 if (s[nowpd]s[nowpc]) d;
38 fail[c]d;
39 }
40 lastlnowl;
41 lasta1;
42 bfail[lastl-1];
43 }
44 else
45 {
46 if (blastl)
47 {
48 lasta1;
49 bfail[b-1];
50 }
51 }
52 }
53 printf(Case %d: %d\n,p,n-lastlastl);
54 }
55
56 return 0;
57 } 第三题 神题…………考试的时候想多了所以打的表………… 那一大堆结论的证明自己去看当天的题解吧我说说一种做法。 考虑一个质数的循环节既然是小于2n2的那么我们对每一个质因数的循环节暴力找出有多长即可了因为最大的质因数也不大然后考虑将各个质因数组合起来的方式利用题解中那个公式就行了总之一切皆为暴力。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 5 using namespace std;6 7 #ifdef unix8 #define LL %lld9 #else
10 #define LL %I64d
11 #endif
12
13 const int maxn1000000;
14
15 int n;
16
17 long long gcd(long long a,long long b)
18 {
19 if (a % b0) return b;
20 else return gcd(b,a%b);
21 }
22
23 int find(int mo)
24 {
25 int a1,b1,c0,d2;
26 while(true)
27 {
28 d;
29 cab;
30 if (cmo) c-mo;
31 ba;
32 ac;
33 if (a1 b0) return d-1;
34 }
35 return -1;
36 }
37
38 int main()
39 {
40 int t;
41 scanf(%d,t);
42 for (int p1;pt;p)
43 {
44 scanf(%d,n);
45 if (n1)
46 {
47 printf(1\n);
48 continue;
49 }
50 long long ans1;
51 for (int a2;a*an;a)
52 if (n % a0)
53 {
54 int nowansfind(a);
55 n/a;
56 while (n%a0)
57 {
58 n/a;
59 nowans*a;
60 }
61 ansans/gcd(ans,nowans)*nowans;
62 }
63 if (n!1)
64 {
65 int nowansfind(n);
66 ansans/gcd(ans,nowans)*nowans;
67 }
68 printf(LL \n,ans);
69 }
70 } Day 2 第一题 这题太囧了啊………………我树分治T到不行…………暴力的反而跑得硕快无比………… 我最后是这样做的因为对于一棵子树只用考虑过根的路径那么我们对每棵子树建一棵splay维护它这棵子树中的每个节点到它的距离进行合并的时候启发式合并即可。当然你构造一根链我就GG了………………………然后你每次而二分个答案然后找出比这个大的路径有多少就可以判定答案了………………判定可以用维护的那个splay乱搞就行了…………囧……………… View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includealgorithm5 6 using namespace std;7 8 const int maxn50010;9 const int maxm300010;10 const int maxp5000010;11 const int INF0x3f3f3f3f;12 13 int en,nowlimit,n,m,ans[maxm],now,cnt,z[maxn],nowl,l;14 15 bool flag;16 17 struct node18 {19 node *l,*r,*f;20 int size,cnt,v;21 node()22 {23 lrfNULL;24 sizecntv0;25 }26 }pp[maxp],*ppppp;27 28 node *newnode()29 {30 return ppp;31 }32 33 struct splay_tree34 {35 node *root;36 void clear()37 {38 rootNULL;39 }40 void update(node *p)41 {42 p-sizep-cnt;43 if (p-l) p-sizep-l-size;44 if (p-r) p-sizep-r-size;45 }46 void rot_l(node *now)47 {48 node *xnow-r;49 now-rx-l;50 x-lnow;51 if (now-fNULL) rootx;52 else53 {54 if (now-f-lnow) now-f-lx;55 else now-f-rx;56 }57 x-fnow-f;58 now-fx;59 if (now-r) now-r-fnow;60 update(now);61 update(x);62 }63 void rot_r(node *now)64 {65 node *xnow-l;66 now-lx-r;67 x-rnow;68 if (now-fNULL) rootx;69 else70 {71 if (now-f-lnow) now-f-lx;72 else now-f-rx;73 }74 x-fnow-f;75 now-fx;76 if (now-l) now-l-fnow;77 update(now);78 update(x);79 }80 void splay(node *now,node *goal)81 {82 while (now-f!goal)83 {84 node *fnow-f;85 node *fff-f;86 if (ffgoal)87 {88 if (f-lnow) rot_r(f);89 else rot_l(f);90 }91 else92 {93 if (ff-lf f-lnow)94 {95 rot_r(ff);96 rot_r(f);97 }98 if (ff-lf f-rnow)99 {
100 rot_l(f);
101 rot_r(ff);
102 }
103 if (ff-rf f-lnow)
104 {
105 rot_r(f);
106 rot_l(ff);
107 }
108 if (ff-rf f-rnow)
109 {
110 rot_l(ff);
111 rot_l(f);
112 }
113 }
114 }
115 }
116 void insert(int v)
117 {
118 if (rootNULL)
119 {
120 rootnewnode();
121 root-cnt1;
122 root-size1;
123 root-vv;
124 }
125 else
126 {
127 node *proot,*lastp;
128 while (p)
129 {
130 if (p-vv)
131 {
132 p-cnt;
133 splay(p,NULL);
134 return;
135 }
136 lastpp;
137 if (p-vv) pp-r;
138 else pp-l;
139 }
140 pnewnode();
141 p-cntp-size1;
142 p-vv;
143 p-flastp;
144 if (vlastp-v) lastp-lp;
145 else lastp-rp;
146 splay(p,NULL);
147 }
148 }
149 int count(int v)
150 {
151 node *proot;
152 int ans0;
153 while (true)
154 {
155 if (vp-v)
156 {
157 if (p-r) pp-r;
158 else
159 {
160 splay(p,NULL);
161 return ans;
162 }
163 }
164 else
165 {
166 ansp-cnt;
167 if (p-r) ansp-r-size;
168 if (p-vv)
169 {
170 splay(p,NULL);
171 return ans;
172 }
173 else
174 {
175 if (p-l) pp-l;
176 else
177 {
178 splay(p,NULL);
179 return ans;
180 }
181 }
182 }
183 }
184 return ans;
185 }
186 void dfs(node *p)
187 {
188 if (!p) return;
189 dfs(p-l);
190 for (int a1;ap-cnt;a)
191 {
192 l;
193 z[l]p-v;
194 }
195 dfs(p-r);
196 }
197 void dfs2(node *p)
198 {
199 if (!p) return;
200 for (int a1;ap-cnt;a)
201 {
202 nowl;
203 ans[nowl]p-v;
204 }
205 dfs2(p-l);
206 dfs2(p-r);
207 }
208 void outit(int v)
209 {
210 node *proot;
211 while (true)
212 {
213 if (vp-v)
214 {
215 if (p-r) pp-r;
216 else
217 {
218 splay(p,NULL);
219 return;
220 }
221 }
222 else
223 {
224 for (int a1;ap-cnt;a)
225 {
226 nowl;
227 ans[nowl]p-v;
228 }
229 if (p-r) dfs2(p-r);
230 if (p-vv)
231 {
232 splay(p,NULL);
233 return;
234 }
235 else
236 {
237 if (p-l) pp-l;
238 else
239 {
240 splay(p,NULL);
241 return;
242 }
243 }
244 }
245 }
246 }
247 }tree[maxn];
248
249 struct edge
250 {
251 int e,d;
252 edge *next;
253 }*v[maxn],ed[maxn1];
254
255 void add_edge(int s,int e,int d)
256 {
257 en;
258 ed[en].nextv[s];v[s]eden;v[s]-ee;v[s]-dd;
259 }
260
261 void merge(splay_tree t1,splay_tree t2,int limit)
262 {
263 if (t1.root-sizet2.root-size) swap(t1,t2);
264 l0;
265 t2.dfs(t2.root);
266 for (int a1;al;a)
267 cntt1.count(nowlimit2*limit-z[a]);
268 for (int a1;al;a)
269 t1.insert(z[a]);
270 }
271
272 void getans(splay_tree t1,splay_tree t2,int limit)
273 {
274 if (t1.root-sizet2.root-size) swap(t1,t2);
275 l0;
276 t2.dfs(t2.root);
277 for (int a1;al;a)
278 {
279 int lastlnowl;
280 t1.outit(nowlimit2*limit-z[a]);
281 for (int blastl1;bnowl;b)
282 ans[b]z[a]-2*limit;
283 }
284 for (int a1;al;a)
285 t1.insert(z[a]);
286 }
287
288 void dfs(int now,int pre,int dist)
289 {
290 tree[now].insert(dist);
291 for (edge *ev[now];e;ee-next)
292 if (e-e!pre)
293 {
294 dfs(e-e,now,diste-d);
295 if (flag) getans(tree[now],tree[e-e],dist);
296 else merge(tree[now],tree[e-e],dist);
297 }
298 }
299
300 void check(int limit)
301 {
302 cnt0;
303 nowlimitlimit;
304 for (int a1;an;a)
305 tree[a].clear();
306 dfs(1,0,0);
307 }
308
309 int main()
310 {
311
312 scanf(%d%d,n,m);
313 for (int a1;an;a)
314 {
315 int s,e,d;
316 scanf(%d%d%d,s,e,d);
317 add_edge(s,e,d);
318 add_edge(e,s,d);
319 }
320 int l0,rINF;
321 while (l1!r)
322 {
323 int mid(lr)1;
324 check(mid);
325 if (cntm) lmid;
326 else rmid;
327 }
328 flagtrue;
329 check(r);
330 sort(ans1,ansm1);
331 for (int am;a1;a--)
332 printf(%d\n,ans[a]);
333
334 return 0;
335 } 第二题 DP。 考虑对人员安排顺序固定了的一个序列我们可以用f[i][j][k]表示前i个人放在了前j个位置且最后d个位置的的状态为k的方案数这个dp还是比较水的。 然后我们考虑如何定序假设我们有一个已有序列那么我们需要放入下一个人考虑由于每个人与他的朋友的距离都不能超过d那么我们下一个放入的人一定是与已在序列中是朋友数最多的人感觉很显然如果有多个这样的人那么我们需要放入的就是这些人中与不在序列中的人朋友最少的还是很显然如果有多个这样的人那么他们是同构的那么这个时候就把他们都加入序列因为他们是同构的也就是说当我们确定了第一个人是谁之后整个序列也随之确定那么问题迎刃而解。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includealgorithm5 6 using namespace std;7 8 const int maxn52;9 const int maxm110;10 const int maxd8;11 const int mo1000000007;12 const int INF0x3f3f3f3f;13 14 #define inc(a,b) {(a)(b);if ((a)mo) (a)-mo;}15 16 int in[maxn],to[maxn],f[maxn][maxm][1maxd],q[maxn],n,m,d;17 18 char s[maxn][maxn];19 20 bool use[maxn];21 22 bool check()23 {24 for (int a1;an;a)25 for (int ba-1;b1;b--)26 if (!s[q[a]][q[b]])27 {28 for (int cb-1;c1;c--)29 if (s[q[a]][q[c]]) return false;30 break;31 }32 for (int a1;an;a)33 for (int ba-d-1;b1;b--)34 if (s[q[a]][q[b]]) return false;35 return true;36 }37 38 39 int dp()40 {41 if (!check()) return 0;42 int ans0;43 memset(f,0,sizeof(f));44 for (int a1;am;a)45 f[1][a][1]1;46 for (int a1;an;a)47 for (int ba;bm;b)48 for (int c0;c(1d);c)49 if (f[a][b][c])50 {51 if (s[q[a]][q[a1]])52 {53 int nowpa-1;54 while (nowp s[q[nowp]][q[a1]])55 nowp--;56 nowp;57 int nowsc;58 int cnt0,p-1;59 while (nows)60 {61 if (nows1) cnt;62 nows1;63 p;64 if (nowpcnta1)65 {66 int pp0,nowsc,cntt0,uf-INF;67 while (nows)68 {69 if (nows1) cntt;70 if (!s[q[a-cntt1]][q[a1]])71 {72 ufb-pp;73 break;74 }75 pp;76 nows1;77 }78 for (int emax(ufd1,b1);eb-pd;e)79 inc(f[a1][e][(1|((c((1(db-e))-1))(e-b)))((1d)-1)],f[a][b][c]);80 break;81 }82 }83 }84 else85 {86 for (int ebd1;em;e)87 inc(f[a1][e][1],f[a][b][c]);88 }89 }90 for (int an;am;a)91 for (int b0;b(1d);b)92 if (f[n][a][b]) inc(ans,f[n][a][b]);93 return ans;94 }95 96 int dfs(int nowp)97 {98 if (nowpn) return dp();99 int nowans0,nowinmax-1,nowoutminINF;
100 for (int a1;an;a)
101 if (!use[a])
102 {
103 if (in[a]nowinmax)
104 {
105 nowinmaxin[a];
106 nowoutminto[a]-in[a];
107 }
108 if (in[a]nowinmax nowoutminto[a]-in[a]) nowoutminto[a]-in[a];
109 }
110 int cnt0;
111 for (int a1;an;a)
112 if (!use[a] in[a]nowinmax nowoutminto[a]-in[a])
113 {
114 cnt;
115 q[nowpcnt-1]a;
116 use[a]true;
117 }
118 for (int anowp;anowpcnt-1;a)
119 for (int b1;bn;b)
120 in[b]s[q[a]][b];
121 nowansdfs(nowpcnt);
122 for (int a1;acnt;a)
123 nowans(long long)nowans*a%mo;
124 for (int anowp;anowpcnt-1;a)
125 for (int b1;bn;b)
126 in[b]-s[q[a]][b];
127 for (int anowp;anowpcnt-1;a)
128 use[q[a]]false;
129 return nowans;
130 }
131
132 int main()
133 {
134
135 scanf(%d%d%d,m,n,d);
136 for (int a1;an;a)
137 scanf(%s,s[a]1);
138 for (int a1;an;a)
139 for (int b1;bn;b)
140 if (s[a][b]Y) s[a][b]1,to[a];
141 else s[a][b]0;
142 int ans0;
143 for (int a1;an;a)
144 {
145 q[1]a;
146 for (int b1;bn;b)
147 in[b]s[a][b];
148 use[a]true;
149 inc(ans,dfs(2));
150 use[a]false;
151 for (int b1;bn;b)
152 in[b]-s[a][b];
153 }
154 printf(%d\n,ans);
155
156 return 0;
157 } 第三题 这题jzp讲了一种logn的做法但是没听懂…………囧………… 这道题其实有sqrt(n)的做法因为考虑我们可以暴力出前sqrt(n)个数的值那么考虑对于下sqrt(n)个数的值的一个分子增量范围是可以算出来的并且会有一部分的增量比另外一部分多1那么我们可以根据它们原来的关于模B的值排序每次就可以二分出变化位置从而推出下sqrt(n)个数的和。然后就可以做sqrt(n)次之后算出所有的答案。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includecmath5 #includealgorithm6 7 using namespace std;8 9 #ifdef unix
10 #define LL %lld
11 #else
12 #define LL %I64d
13 #endif
14
15 const int maxn100000;
16 const long long mo1000000007;
17
18 long long va,vb,vc,l,r;
19
20 struct state
21 {
22 long long mod,x,y,z;
23 bool operator(const state a)const
24 {
25 return moda.mod;
26 }
27 }s[maxn],sum[maxn],bsum[maxn];
28
29 int find(int size,long long delta_mod)
30 {
31 if (delta_mods[1].mod) return 1;
32 if (delta_mods[size].mod) return size1;
33 int l0,rsize;
34 while (l1!r)
35 {
36 int m(lr)1;
37 if (s[m].moddelta_mod) rm;
38 else lm;
39 }
40 return r;
41 }
42
43 long long getans(int size,long long nowp)
44 {
45 long long delta_modnowp*va%vb;
46 int pfind(size,vb-delta_mod);
47 long long deltavnowp*va/vb%mo;
48 long long ans0;
49 long long deltanowp;
50 p--;
51 if (p) ans(anssum[p].zsum[p].x*deltav%modelta*sum[p].y%modelta*deltav%mo*p%mo)%mo;
52 p;
53 deltav;
54 if (psize) ans(ansbsum[p].zbsum[p].x*deltav%modelta*bsum[p].y%modelta*deltav%mo*(size-p1)%mo)%mo;
55 return ans;
56 }
57
58 long long solve(long long p)
59 {
60 if (p0) return 0;
61 int size(int)sqrt(p);
62 for (int a1;asize;a)
63 {
64 s[a].mod(va*avc)%vb;
65 s[a].xa;
66 s[a].y(va*avc)/vb%mo;
67 s[a].zs[a].x*s[a].y%mo;
68 }
69 sort(s1,ssize1);
70 sum[0].xsum[0].ysum[0].z0;
71 for (int a1;asize;a)
72 sum[a].x(sum[a-1].xs[a].x)%mo,sum[a].y(sum[a-1].ys[a].y)%mo,sum[a].z(sum[a-1].zs[a].z)%mo;
73 bsum[size1].xbsum[size1].ybsum[size1].z0;
74 for (int asize;a1;a--)
75 bsum[a].x(bsum[a1].xs[a].x)%mo,bsum[a].y(bsum[a1].ys[a].y)%mo,bsum[a].z(bsum[a1].zs[a].z)%mo;
76 long long nowp1,ans0;
77 while (nowpsize-1p)
78 {
79 ans(ansgetans(size,nowp-1))%mo;
80 nowpsize;
81 }
82 for (long long anowp;ap;a)
83 ans(ans(va*avc)/vb%mo*a%mo)%mo;
84 return ans;
85 }
86
87 int main()
88 {
89 scanf(LL LL LL LL LL,va,vb,vc,l,r);
90 printf(LL \n,(solve(r)-solve(l-1)mo)%mo);
91
92 return 0;
93 } Day 3 第一题 这道题最大的很好做做最小的时候每次二分这个政党最少能够获得多少席位然后用一个背包DP检验即可。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includealgorithm5 6 using namespace std;7 8 const int maxn110;9 10 int z[maxn],s[maxn],v,n,m,maxv[maxn],sum,x[maxn],minv[maxn],f[2][maxn1];11 12 struct rec13 {14 int v,p;15 bool operator(const rec a)const16 {17 return va.v;18 }19 }y[maxn];20 21 int calc(int p)22 {23 for (int a1;an;a)24 s[a]0;25 for (int a1;am;a)26 {27 pairint,int nowvmake_pair(0,1);28 int nowp-1;29 for (int b1;bn;b)30 if (z[b]*20v nowv.first*(s[b]1)nowv.second*z[b])31 {32 nowvmake_pair(z[b],s[b]1);33 nowpb;34 }35 if (nowp-1) break;36 s[nowp];37 }38 return s[p];39 }40 41 bool check(int p,int goal)42 {43 int last0,src1,limitm-goal;44 for (int a1;alimit;a)45 f[src][a]v1;46 f[src][0]0;47 for (int a1;an;a)48 if (a!p)49 {50 src^1;51 last^1;52 for (int b0;blimit;b)53 f[src][b]f[last][b];54 for (int b1;blimit;b)55 {56 int needz[p]*b/(goal1)1;57 if (z[p]*b%(goal1)0) need--;58 if (need*20v)59 {60 needv/20;61 if (need*20v) need;62 }63 need-z[a];64 if (need0) need0;65 for (int cb;climit;c)66 f[src][c]min(f[src][c],f[last][c-b]need);67 }68 }69 return f[src][limit]v-sum;70 }71 72 int main()73 {74 scanf(%d%d%d,v,n,m);75 for (int a1;an;a)76 scanf(%d,z[a]),sumz[a];77 for (int a1;an;a)78 {79 z[a]v-sum;80 maxv[a]calc(a);81 z[a]-v-sum;82 }83 for (int a1;an;a)84 {85 printf(%d,maxv[a]);86 if (an) printf(\n);87 else printf( );88 }89 for (int a1;an;a)90 if (z[a]*20v || n1)91 {92 int l-1,rm;93 while (l1r)94 {95 int m(lr)1;96 if (check(a,m)) rm;97 else lm;98 }99 minv[a]r;
100 }
101 for (int a1;an;a)
102 {
103 printf(%d,minv[a]);
104 if (an) printf(\n);
105 else printf( );
106 }
107
108 return 0;
109 } 第二题 这题是神一般的DP用f[i][j][k]表示从i点走到j点走了k步没有剩余字母的方案数用g[i][j][k]表示从i点走到j点走了k步没有剩余字母且字母是在最后一步被消耗光的方案数用h[i][j][k]表示从i点走到j点走了k步并且有字母剩余的方案数然后三个互相推就可以转移了。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includevector5 #includemap6 7 using namespace std;8 9 const int maxn52;10 const int maxmmaxn*maxn;11 const int mo10007;12 13 #define inc(a,b) {ab;if (amo) a-mo;}14 15 int en,n,m,k,g[maxn][maxn][maxn],f[maxn][maxn][maxn],h[maxn][maxn][maxn];16 17 int s1[maxm],e1[maxm],t1[maxm],cnt1;18 19 int s2[maxm],e2[maxm],t2[maxm],cnt2;20 21 struct edge22 {23 int e;24 char v;25 edge *next;26 }*v[maxn],ed[maxn*maxn],*v2[maxn];27 28 void add_edge(int s,int e,char c)29 {30 en;31 ed[en].nextv[s];v[s]eden;v[s]-ee;v[s]-vc;32 cnt1;33 s1[cnt1]s;e1[cnt1]e;t1[cnt1]c;34 if (c!!) t1[cnt1]-A-1;35 else t1[cnt1]0;36 }37 38 void add_edge2(int s,int e,char c)39 {40 en;41 ed[en].nextv2[s];v2[s]eden;v2[s]-ee;v2[s]-vc;42 cnt2;43 s2[cnt2]s;e2[cnt2]e;t2[cnt2]c-a1;44 }45 46 int main()47 {48 scanf(%d%d%d,n,m,k);49 for (int a1;am;a)50 {51 int s,e;52 scanf(%d%d,s,e);53 char c!;54 bool findfalse;55 while (~scanf(%c,c))56 {57 if (c\n || c\r) break;58 if ((cA cZ) || (ca cz))59 {60 findtrue;61 if (cA cZ) add_edge(s,e,c);62 else add_edge2(s,e,c);63 break;64 }65 }66 if (!find) c!,add_edge(s,e,c);67 }68 for (int a1;an;a)69 f[a][a][0]1,g[a][a][0]1;70 for (int a1;acnt1;a)71 for (int b1;bcnt2;b)72 if (e1[a]s2[b] t1[a]t2[b]) g[s1[a]][e2[b]][2];73 for (int a1;ak;a)74 {75 for (int b1;bn;b)76 for (int c1;cn;c)77 {78 int xf[b][c][a];79 for (edge *ev[b];e;ee-next)80 if (e-v!)81 {82 xf[e-e][c][a-1];83 if (xmo) x-mo;84 }85 for (int d1;dn;d)86 for (int e2;ea;e)87 x(xg[b][d][e]*f[d][c][a-e])%mo;88 }89 if (a2k)90 {91 for (int b1;bcnt1;b)92 if (t1[b])93 for (int c1;ccnt2;c)94 if (t1[b]t2[c]) 95 {96 int xg[s1[b]][e2[c]][a2];97 xf[e1[b]][s2[c]][a];98 if (xmo) x-mo;99 }
100 }
101 }
102 for (int a1;acnt1;a)
103 if (t1[a]) h[s1[a]][e1[a]][1];
104 for (int a2;ak;a)
105 for (int b1;bn;b)
106 for (int c1;cn;c)
107 {
108 int xh[b][c][a];
109 for (edge *ev[b];e;ee-next)
110 if (e-v!!)
111 {
112 xh[e-e][c][a-1]f[e-e][c][a-1];
113 if (xmo) x-mo;
114 if (xmo) x-mo;
115 }
116 else
117 {
118 xh[e-e][c][a-1];
119 if (xmo) x-mo;
120 }
121 for (int d1;dn;d)
122 for (int e2;ea;e)
123 x(xg[b][d][e]*h[d][c][a-e])%mo;
124 }
125 int ans0;
126 for (int a0;ak;a)
127 ans(ansf[1][n][a]h[1][n][a])%mo;
128 printf(%d\n,ans);
129
130 return 0;
131 } 第三题 可以很容易发现题目就是问一条直线YkXb中的b最大值那么考虑这个问题实际上就是在一个上凸壳中询问一条与y轴截距最大的直线那么每次二分答案就可以解决了。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 5 using namespace std;6 7 #ifdef unix8 #define LL %lld9 #else
10 #define LL %I64d
11 #endif
12
13 const int maxn100010;
14
15 int n,m,size;
16
17 long long x[maxn],y[maxn],sum[maxn],f[maxn];
18
19 long long cross(long long x1,long long y1,long long x2,long long y2)
20 {
21 return x1*y2-x2*y1;
22 }
23
24 void get_hull()
25 {
26 x[1]0;y[1]sum[1];
27 x[2]sum[1];y[2]sum[2];
28 size2;
29 for (int a3;an;a)
30 {
31 long long xxsum[a-1],yysum[a];
32 while (size cross(xx-x[size],yy-y[size],xx-x[size-1],yy-y[size-1])0)
33 size--;
34 size;
35 x[size]xx;
36 y[size]yy;
37 }
38 }
39
40 int main()
41 {
42
43 scanf(%d%d,n,m);
44 for (int a1;an;a)
45 scanf(LL,sum[a]),sum[a]sum[a-1];
46 for (int a1;am;a)
47 scanf(LL,f[a]);
48 get_hull();
49 long long ans0;
50 for (int a2;am;a)
51 {
52 if (size1) ansf[a-1]*y[1];
53 else
54 {
55 if (cross(f[a-1],f[a],x[2]-x[1],y[2]-y[1])0) ansf[a-1]*y[1]-f[a]*x[1];
56 else
57 {
58 if (cross(x[size]-x[size-1],y[size]-y[size-1],f[a-1],f[a])0) ansf[a-1]*y[size]-f[a]*x[size];
59 else
60 {
61 int l2,rsize1;
62 while (l1!r)
63 {
64 int m(lr)1;
65 if (cross(x[m]-x[m-1],y[m]-y[m-1],f[a-1],f[a])0) lm;
66 else rm;
67 }
68 ansf[a-1]*y[l]-f[a]*x[l];
69 }
70 }
71 }
72 }
73 anssum[n]*f[m];
74 printf(LL \n,ans);
75
76 return 0;
77 } Day 4 第一题 这题太囧了………………其实就是要求动态维护重心……………… 考虑每次合并两颗子树的时候新的重心一定在两颗树的原来之间的路径上那么我们可以用LCT将这两个点到他们的LCA的路径搞出来然后我们中途动态维护一些值就可以做了这种做法可以去看fhq的博客。 我用的是一种囧到不能再囧的方法…………我们先把所有询问离线然后在预处理时只考虑加边操作每次进行启发式合并将小树的dfs序并到大树的dfs序的后面去这样可以在O(nlogn)的时间内将所有时刻对应的不同的dfs序给搞出来。然后再来做询问考虑每次需要维护重心而重心只会在加边的时候改变。这个时候我们暴力修改小树的倍增父亲的值然后找出原来两个重心的LCA然后就相当于是在这两个链上找到一个重心。考虑我们从大树的重心向上移每移一次我们需要知道所有点到这两个点的距离总和相当于只要我们知道这棵子树的大小就可以算出这个差量了。由于我们之前维护了一个任意时刻的dfs序所以我们直接使用树状数组维护每一个dfs序这样就可以询问一颗子树的当前大小从而解决这个增量的问题。然后可以发现这个是有一定的单调性的所以利用那个维护的倍增父亲的值就可以顺利解决了。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includevector5 6 using namespace std;7 8 const int maxn100010;9 const int maxq200010;10 11 #define lb(a) ((a)(-(a)))12 13 int n,m,en,depth[maxn],q[maxq][3],size[maxn],root[maxn],f[maxn][20],mid[maxn],id[maxn],idx,p[maxn],belong[maxqmaxn],tmp,ans;14 15 char s[10];16 17 struct rec18 {19 int id,pos;20 rec(){}21 rec(int a,int b)22 {23 ida;posb;24 }25 };26 27 vectorrec into[maxn],outto[maxn];28 29 vectorint tree[maxq];30 31 struct edge32 {33 int e;34 edge *next;35 }*v[maxn],ed[maxn1];36 37 void add_edge(int s,int e)38 {39 en;40 ed[en].nextv[s];v[s]eden;v[s]-ee;41 }42 43 void add(int id,int p)44 {45 while (p(int)tree[id].size())46 {47 tree[id][p];48 plb(p);49 }50 }51 52 int query(int id,int p)53 {54 int ans0;55 while (p)56 {57 anstree[id][p];58 p-lb(p);59 }60 return ans;61 }62 63 void build(int now,int fa,int id)64 {65 if (fa0) tree[id].push_back(0);66 tree[id].push_back(0);67 into[now].push_back(rec(id,tree[id].size()-1));68 for (edge *ev[now];e;ee-next)69 if (e-e!fa) build(e-e,now,id);70 tree[id].push_back(0);71 outto[now].push_back(rec(id,tree[id].size()-1));72 }73 74 void change(int now,int fa,int rt,bool dep)75 {76 root[now]rt;77 if (dep)78 {79 depth[now]depth[fa]1;80 memset(f[now],0,sizeof(f[now]));81 f[now][0]fa;82 int x0,nowpfa;83 while (f[nowp][x])84 {85 f[now][x1]f[nowp][x];86 nowpf[nowp][x];87 x;88 }89 }90 for (edge *ev[now];e;ee-next)91 if (e-e!fa) change(e-e,now,rt,dep);92 }93 94 void prepare()95 {96 for (int a1;an;a)97 {98 size[a]depth[a]1;99 root[a]id[a]a;
100 }
101 idxn;
102 for (int a1;am;a)
103 if (q[a][0]1)
104 {
105 int p1q[a][1],p2q[a][2];
106 if (size[root[p1]]size[root[p2]]) swap(p1,p2);
107 if (size[root[p1]]size[root[p2]] p1p2) swap(p1,p2);
108 int r1root[p1],r2root[p2];
109 size[r1]size[r2];
110 build(r2,0,id[r2]);
111 add_edge(p1,p2);
112 add_edge(p2,p1);
113 change(p2,p1,r1,false);
114 idx;
115 belong[id[r1]]idx;
116 id[r1]idx;
117 }
118 for (int a1;an;a)
119 if (root[a]a) build(a,0,id[a]);
120 for (int aidx;a1;a--)
121 if (belong[a]0) belong[a]a;
122 else belong[a]belong[belong[a]];
123 }
124
125 void insert(int now,int id)
126 {
127 while (into[now][p[now]].id!id)
128 p[now];
129 add(id,into[now][p[now]].pos);
130 }
131
132 void insert(int now,int fa,int id)
133 {
134 insert(now,id);
135 for (edge *ev[now];e;ee-next)
136 if (e-e!fa) insert(e-e,now,id);
137 }
138
139 int get_lca(int p1,int p2)
140 {
141 if (depth[p1]depth[p2]) swap(p1,p2);
142 int deltadepth[p1]-depth[p2],x0;
143 while (delta)
144 {
145 if (delta1) p1f[p1][x];
146 x;
147 delta1;
148 }
149 x0;
150 while (p1!p2)
151 {
152 if (!x || f[p1][x]!f[p2][x])
153 {
154 p1f[p1][x];
155 p2f[p2][x];
156 x;
157 }
158 else x--;
159 }
160 return p1;
161 }
162
163 int get_sum(int now,int id)
164 {
165 int ans0;
166 while (outto[now][p[now]].id!id)
167 p[now];
168 ansquery(id,outto[now][p[now]].pos);
169 while (into[now][p[now]].id!id)
170 p[now];
171 ans-query(id,into[now][p[now]].pos-1);
172 return ans;
173 }
174
175 int get_sum2(int now,int id)
176 {
177 int ans0;
178 int l-1,routto[now].size()-1;
179 while (l1!r)
180 {
181 int m(lr)1;
182 if (outto[now][m].idid) rm;
183 else lm;
184 }
185 ansquery(id,outto[now][r].pos);
186 l-1,rinto[now].size()-1;
187 while (l1!r)
188 {
189 int m(lr)1;
190 if (into[now][m].idid) rm;
191 else lm;
192 }
193 ans-query(id,into[now][r].pos-1);
194 return ans;
195 }
196
197 int get_next(int p1,int p2)
198 {
199 int deltadepth[p2]-depth[p1]-1;
200 int x0;
201 if (delta0) return -1;
202 while (delta)
203 {
204 if (delta1) p2f[p2][x];
205 x;
206 delta1;
207 }
208 return p2;
209 }
210
211 void get_change(int nowmid,int idx,int next)
212 {
213 int pnowmid;
214 int epf[nowmid][0];
215 int delta;
216 if (ep)
217 {
218 deltasize[root[nowmid]]-2*get_sum2(nowmid,belong[idx]);
219 if (delta0 epp) pep;
220 }
221 if (next!-1)
222 {
223 deltasize[root[nowmid]]-2*get_sum2(next,belong[idx]);
224 if (delta0 nextp) pnext;
225 }
226 nowmidp;
227 }
228
229 int dfs(int now,int fa)
230 {
231 int nowsum1;
232 for (edge *ev[now];e;ee-next)
233 if (e-e!fa) nowsumdfs(e-e,now);
234 tmpnowsum;
235 return nowsum;
236 }
237
238 void solve()
239 {
240 en0;
241 for (int a1;an;a)
242 {
243 size[a]1;
244 root[a]mid[a]id[a]a;
245 insert(a,belong[a]);
246 v[a]NULL;
247 ans^a;
248 }
249 idxn;
250 for (int a1;am;a)
251 if (q[a][0]2) printf(%d\n,ans);
252 else
253 {
254 if (q[a][0]3) printf(%d\n,mid[root[q[a][1]]]);
255 else
256 {
257 int p1q[a][1],p2q[a][2];
258 if (size[root[p1]]size[root[p2]]) swap(p1,p2);
259 if (size[root[p1]]size[root[p2]] p1p2) swap(p1,p2);
260 int r1root[p1],r2root[p2];
261 int ans1mid[r1],ans2mid[r2];
262 size[r1]size[r2];
263 add_edge(p1,p2);
264 add_edge(p2,p1);
265 change(p2,p1,r1,true);
266 int lcaget_lca(mid[r1],p1);
267 idx;
268 id[r1]idx;
269 insert(p2,p1,belong[idx]);
270 tmp0;
271 dfs(p2,p1);
272 int nowmidmid[r1];
273 while (nowmid!lca)
274 {
275 int nowsumget_sum(nowmid,belong[idx]);
276 if (size[r1](nowsum1)) nowmidf[nowmid][0];
277 else break;
278 }
279 if (nowmid!lca)
280 {
281 int nextget_next(nowmid,r1);
282 get_change(nowmid,idx,next);
283 mid[r1]nowmid;
284 ans^mid[r1]^ans1^ans2;
285 continue;
286 }
287 int x0;
288 nowmidp1;
289 while (f[nowmid][x])
290 x;
291 while (x0)
292 {
293 if (f[nowmid][x])
294 {
295 int nowsumget_sum(f[nowmid][x],belong[idx]);
296 if (size[r1](nowsum1)) nowmidf[nowmid][x];
297 }
298 x--;
299 }
300 tmp2*get_sum(nowmid,belong[idx])-size[r1];
301 if (tmp0 f[nowmid][0]) nowmidf[nowmid][0];
302 int nextget_next(nowmid,p1);
303 get_change(nowmid,idx,next);
304 mid[r1]nowmid;
305 ans^ans1^ans2^mid[r1];
306 }
307 }
308 }
309
310 int main()
311 {
312 scanf(%d%d,n,m);
313 for (int a1;am;a)
314 {
315 scanf(%s,s);
316 if (s[0]A)
317 {
318 q[a][0]1;
319 scanf(%d%d,q[a][1],q[a][2]);
320 }
321 else
322 {
323 if (s[0]X) q[a][0]2;
324 else
325 {
326 q[a][0]3;
327 scanf(%d,q[a][1]);
328 }
329 }
330 }
331 prepare();
332 solve();
333
334 return 0;
335 } 第二题 这个…………网络流应该是很明显的…………问题就是建模吧………… 建模方式如下 1、 首先将每个点的va、vb值乘二。 2、 将每条边的ea、eb值加上ec。 3、 将ans记为当前所有的va、vb之和加上每条边的三种权值之和。 4、 从源点向每个点连一条容量为va的边 5、 从每个点向汇点连一条容量为vb的边 6、 对于一条边将起点和终点之间连一条容量为eaeb2*ec的边。 那么最后的答案即为(ans-最大流)/2。 至于这个模型的正确性只需要考虑其割集的意义便可以很容易的证明了。如果有人不懂的话我再把那个囧图画出来吧……………… View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includealgorithm5 6 using namespace std;7 8 #ifdef unix9 #define LL %lld10 #else11 #define LL %I64d12 #endif13 14 const int maxn10010*2;15 const int maxm40010*6;16 const long long INF123456789876543ll;17 18 int n,m,en,s,t;19 20 long long va[maxn],vb[maxn],ans,depth[maxn],q[maxn];21 22 struct edge23 {24 int e;25 long long f;26 edge *next,*op;27 }*v[maxn],ed[maxm];28 29 void add_edge(int s,int e,long long f)30 {31 en;32 ed[en].nextv[s];v[s]eden;v[s]-ee;v[s]-ff;33 en;34 ed[en].nextv[e];v[e]eden;v[e]-es;v[e]-f0;35 v[s]-opv[e];v[e]-opv[s];36 }37 38 bool bfs()39 {40 memset(depth,0,sizeof(depth));41 depth[s]1;42 int front1,tail1;43 q[front]s;44 while (fronttail)45 {46 int nowq[front];47 front;48 for (edge *ev[now];e;ee-next)49 if (e-f !depth[e-e])50 {51 depth[e-e]depth[now]1;52 tail;53 q[tail]e-e;54 }55 }56 return depth[t]!0;57 }58 59 long long dfs(int now,long long cur_flow)60 {61 if (nowt) return cur_flow;62 long long restcur_flow;63 for (edge *ev[now];e;ee-next)64 if (e-f rest depth[e-e]depth[now])65 {66 long long new_flowdfs(e-e,min(e-f,rest));67 e-f-new_flow;68 e-op-fnew_flow;69 rest-new_flow;70 }71 if (cur_flowrest) depth[now]0;72 return cur_flow-rest;73 }74 75 long long dinic()76 {77 long long ans0;78 while (bfs())79 ansdfs(s,INF);80 return ans;81 }82 83 int main()84 {85 scanf(%d%d,n,m);86 for (int a2;an;a)87 {88 scanf(LL,va[a]);89 va[a]1;90 ansva[a];91 }92 for (int a2;an;a)93 {94 scanf(LL,vb[a]);95 vb[a]1;96 ansvb[a];97 }98 va[1]INF;vb[n]INF;99 for (int a1;am;a)
100 {
101 int s,e,ea,eb,ec;
102 scanf(%d%d%d%d%d,s,e,ea,eb,ec);
103 ans(eaebec)1;
104 eaec;
105 ebec;
106 va[s]ea;va[e]ea;
107 vb[s]eb;vb[e]eb;
108 add_edge(s,e,eaeb);
109 add_edge(e,s,eaeb);
110 }
111 s0;tn1;
112 for (int a1;an;a)
113 add_edge(0,a,va[a]);
114 for (int a1;an;a)
115 add_edge(a,n1,vb[a]);
116 printf(LL \n,(ans-dinic())1);
117
118 return 0;
119 } 第三题 这题好像很水的样子啊……………… 考虑有几行被选了奇数次那么有多少列被选了奇数次也就确定了这样一来的话就成了简单的组合计数问题了…………囧……………… View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includealgorithm5 6 using namespace std;7 8 #ifdef unix9 #define LL %lld10 #else11 #define LL %I64d12 #endif13 14 const int maxn100010;15 const int mo1000000007;16 17 int n,m,r,c,ans,v0[maxn],v1[maxn],v2[maxn],v3[maxn],v4[maxn];18 19 long long s;20 21 int multi(long long a,int b)22 {23 a*b;24 if (amo) a%mo;25 return (int)a;26 }27 28 void inc(int a,int b)29 {30 ab;31 if (amo) a-mo;32 }33 34 int mul(int a,int b)35 {36 int ans1;37 while (b)38 {39 if (b1) ansmulti(ans,a);40 amulti(a,a);41 b1;42 }43 return ans;44 }45 46 int main()47 {48 scanf(%d%d%d%d LL,n,m,r,c,s);49 v1[0]1;50 for (int a1;a100000;a)51 v0[a]mul(a,mo-2);52 int tmp1;53 for (int a0;a(r1);a)54 {55 v1[a]tmp;56 tmpmulti(tmp,multi(an,v0[a1]));57 }58 tmp1;59 for (int a0;a(c1);a)60 {61 v2[a]tmp;62 tmpmulti(tmp,multi(am,v0[a1]));63 }64 tmp1;65 for (int a0;an;a)66 {67 v3[a]tmp;68 tmpmulti(tmp,multi(n-a,v0[a1]));69 }70 tmp1;71 for (int a0;am;a)72 {73 v4[a]tmp;74 tmpmulti(tmp,multi(m-a,v0[a1]));75 }76 for (int ar1;amin(n,r);a2)77 if (a*2!n)78 {79 if (((s-(long long)a*m))%(n-a*2)) continue;80 int b(int)((s-(long long)a*m)/(n-a*2));81 if (bc || b0 || ((c-b)1)) continue;82 int nowansv3[a];83 nowansmulti(nowans,v1[(r-a)1]);84 nowansmulti(nowans,v4[b]);85 nowansmulti(nowans,v2[(c-b)1]);86 inc(ans,nowans);87 }88 else89 {90 if ((long long)a*m!s) continue;91 int nowansv3[a];92 nowansmulti(nowans,v1[(r-a)1]);93 int cnt0;94 for (int b(c1);bmin(r,c);b2)95 inc(cnt,multi(v4[b],v2[(c-b)1]));96 inc(ans,multi(ans,cnt));97 }98 printf(%d\n,ans);99
100 return 0;
101 } Day 5 这天的题囧爆了……………… 第一题 由于有第一天第三题…………所以这题就太水了吧…………找出两个数列的循环节然后暴力乱搞就行了吧………… View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 5 using namespace std;6 7 #ifdef unix8 #define LL %lld9 #else10 #define LL %I64d11 #endif12 13 const int maxn200;14 const long long mo1000000007;15 const long long mo2mo*22;16 const long long mo3mo2*3;17 18 char s[maxn];19 20 struct matrix21 {22 long long z[3][3];23 matrix()24 {25 memset(z,0,sizeof(z));26 }27 matrix operator*(const matrix a)const28 {29 matrix ans;30 for (int b1;b2;b)31 for (int c1;c2;c)32 for (int d1;d2;d)33 ans.z[b][c](ans.z[b][c]z[b][d]*a.z[d][c]%mo)%mo;34 return ans;35 }36 matrix operator(const matrix a)const37 {38 matrix ans;39 for (int b1;b2;b)40 for (int c1;c2;c)41 for (int d1;d2;d)42 ans.z[b][c](ans.z[b][c]z[b][d]*a.z[d][c]%mo2)%mo2;43 return ans;44 }45 }m1,m2;46 47 struct bign48 {49 int z[maxn],l;50 void init()51 {52 memset(z,0,sizeof(z));53 scanf(%s,s1);54 lstrlen(s1);55 for (int a1;al;a)56 z[a]s[l-a1]-0;57 }58 long long operator%(const long long a)const59 {60 long long b0;61 for (int cl;c1;c--)62 b(b*10z[c])%a;63 return b;64 }65 }z;66 67 long long get(long long v)68 {69 if (v0) return 0;70 m1.z[1][1]0;71 m1.z[1][2]1;72 m2.z[1][1]0;73 m2.z[1][2]m2.z[2][1]m2.z[2][2]1;74 while (v)75 {76 if (v1) m1m1*m2;77 m2m2*m2;78 v1;79 }80 return m1.z[1][1];81 }82 83 long long get1(long long v)84 {85 if (v0) return 0;86 m1.z[1][1]0;87 m1.z[1][2]1;88 m2.z[1][1]0;89 m2.z[1][2]m2.z[2][1]m2.z[2][2]1;90 while (v)91 {92 if (v1) m1m1m2;93 m2m2m2;94 v1;95 }96 return m1.z[1][1];97 }98 99 int main()
100 {
101 int t;
102 scanf(%d,t);
103 for (int a1;at;a)
104 {
105 z.init();
106 long long v1z % mo3;
107 v1get1(v1);
108 printf(LL \n,get(v1));
109 }
110
111 return 0;
112 } 第二题 题解上说暴力打张表出来…………囧………… View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 5 using namespace std;6 7 char s[2600]3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420198938095257201065485863278;8 9 int n;
10
11 int main()
12 {
13 scanf(%d,n);
14 for (int a0;an;a)
15 printf(%c,s[a]);
16 printf(\n);
17
18 return 0;
19 } 第三题 考虑10^102^10*5^10那么只要分别搞出答案对这两个数的余数然后用中国剩余定理就搞定了其实这里可以暴力……………… 我们这里只考虑C(n,m) mod 2^10的情况等价于n!/m!/(n-m)! mod 2^10很明显我们在算的时候需要把2这个约数单独拿出来考虑那么问题变成了设n!x*2^yx是一个奇数求x mod 2^10我们先把n1024的情况暴力出来之后然后我们发现不考虑偶数的话每1024个数的情况都是一样的这个就可以很快的求出来了。然后我们考虑偶数首先把每个偶数都除以二我们发现这个问题就转化成了一个规模更小的原问题那么递归处理下去就可以了。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 5 using namespace std;6 7 #ifdef unix8 #define LL %lld9 #else
10 #define LL %I64d
11 #endif
12
13 #ifdef unix
14 #define LX %010lld
15 #else
16 #define LX %010I64d
17 #endif
18
19 const long long mo10000000000ll;
20 const long long mo11024;
21 const long long mo29765625;
22
23 long long n,m,v[mo2];
24
25 long long get(long long a,int b)
26 {
27 long long ans0;
28 while (a)
29 {
30 ansa/b;
31 a/b;
32 }
33 return ans;
34 }
35
36 long long mul(long long a,long long b,long long mo)
37 {
38 long long ans1;
39 while (b)
40 {
41 if (b1) ansans*a%mo;
42 aa*a%mo;
43 b1;
44 }
45 return ans;
46 }
47
48 long long fac(long long n,long long div,long long mo)
49 {
50 long long nowans1;
51 if (ndiv) nowansfac(n/div,div,mo);
52 return nowans*(mul(v[mo-1],n/mo,mo)*v[n%mo]%mo)%mo;
53 }
54
55 long long calc(long long n,long long m,long long div)
56 {
57 int sum;
58 if ((sumget(n,div)-get(m,div)-get(n-m,div))10) return 0;
59 long long mo;
60 if (div2) momo1;
61 else momo2;
62 v[0]1;
63 for (int a1;amo;a)
64 v[a]v[a-1]*(a%div?a:1)%mo;
65 return fac(n,div,mo)*mul(fac(m,div,mo)*fac(n-m,div,mo)%mo,mo/div*(div-1)-1,mo)%mo*mul(div,sum,mo)%mo;
66 }
67
68
69 int main()
70 {
71
72 scanf(LL LL,n,m);
73 if (nm)
74 {
75 printf(0000000000\n);
76 return 0;
77 }
78 long long v1calc(n,m,2);
79 long long v2calc(n,m,5);
80 while (v2%mo1!v1)
81 v2mo2;
82 printf(LX \n,v2);
83
84 return 0;
85 } Day 6 第一题 我们把这个问题离线来做我们对B树的每一个点从它自己到根的字符串按照字典序排个序。 然后开始处理询问分两种情况 1、 对A树添加一个节点 考虑新节点的父亲如果我们对新节点的父亲在B那个已经排序好的数组里记录了一个可匹配的区间那么新的节点在那个数组中能够匹配的区间一定是被父亲的区间所包含的且我们在找这个区间时只需要匹配新加入的这个字母。于是我们在这个区间里二分上下界得到一个新的区间那么就处理出了新节点所对应的一个区间。然后这种操作对答案的影响便是这个区间内有多少个B的串已被加入这个可以在没次加入一个B中的结点时用树状数组维护即可。 2、 对B树添加一个结点 考虑这种操作对答案的影响它能带来的影响就是以前有多少个A树中的结点所对应的区间包含了它那么这个也可以用一个树状数组维护即可。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includealgorithm5 6 using namespace std;7 8 #ifdef unix9 #define LL %lld10 #else11 #define LL %I64d12 #endif13 14 #define lb(p) (p)(-(p))15 16 const int maxn100010;17 const unsigned long long base10003;18 19 int n,q[maxn][3],z1[maxn],z2[maxn],f[maxn][20],fe[maxn],cnt2,size1,size2,sa[maxn],rank[maxn],depth1[maxn],depth2[maxn];20 21 long long ans;22 23 unsigned long long bit[maxn],h[maxn];24 25 pairint,int range[maxn];26 27 void change(int *z,int p,int delta)28 {29 while (pcnt2)30 {31 z[p]delta;32 plb(p);33 }34 }35 36 int query(int *z,int p)37 {38 int ans0;39 while (p)40 {41 ansz[p];42 p-lb(p);43 }44 return ans;45 }46 47 bool cmp(int a,int b)48 {49 int x0;50 while ((1x)depth2[a] (1x)depth2[b])51 x;52 for (x--;x0;x--)53 {54 unsigned long long h1h[a]-h[f[a][x]]*bit[1x];55 unsigned long long h2h[b]-h[f[b][x]]*bit[1x];56 if (h1h2) af[a][x],bf[b][x];57 }58 return fe[a]fe[b];59 }60 61 int up(int p,int s)62 {63 int x0;64 while (s)65 {66 if (s1) pf[p][x];67 s1;68 x;69 }70 return p;71 }72 73 int main()74 {75 76 scanf(%d,n);77 bit[0]1;78 for (int a1;an;a)79 bit[a]bit[a-1]*base;80 depth1[1]depth2[1]1;81 cnt21;82 for (int a1;an;a)83 {84 int t,v;85 char s[2],c;86 scanf(%d%d%s,t,v,s);87 cs[0];88 q[a][0]t;q[a][1]v;q[a][2]c;89 if (t2)90 {91 cnt2;92 depth2[cnt2]depth2[v]1;93 fe[cnt2]c;94 h[cnt2]h[v]*basec-a1;95 f[cnt2][0]v;96 int x0;97 while (f[v][x])98 {99 f[cnt2][x1]f[v][x];
100 vf[v][x];
101 x;
102 }
103 }
104 }
105 for (int a1;acnt2;a)
106 sa[a]a;
107 sort(sa1,sacnt21,cmp);
108 for (int a1;acnt2;a)
109 rank[sa[a]]a;
110 size1size21;
111 range[1]make_pair(1,cnt21);
112 for (int a1;an;a)
113 {
114 if (q[a][0]1)
115 {
116 size1;
117 depth1[size1]depth1[q[a][1]]1;
118 if (range[q[a][1]].first!-1)
119 {
120 int lowerrange[q[a][1]].first,upperrange[q[a][1]].second-1;
121 int llower,rupper;
122 while (lr)
123 {
124 int m(lr)1;
125 if (fe[up(sa[m],depth1[size1]-2)]q[a][2]) lm1;
126 else rm-1;
127 }
128 int new_lowerl;
129 llower,rupper;
130 while (lr)
131 {
132 int m(lr)1;
133 if (fe[up(sa[m],depth1[size1]-2)]q[a][2]) rm-1;
134 else lm1;
135 }
136 int new_upperr1;
137 if (new_lowernew_upper) range[size1]make_pair(-1,-1);
138 else
139 {
140 ansquery(z2,new_upper-1)-query(z2,new_lower-1);
141 change(z1,new_lower,1);
142 change(z1,new_upper,-1);
143 range[size1]make_pair(new_lower,new_upper);
144 }
145 }
146 else range[size1]make_pair(-1,-1);
147 }
148 else
149 {
150 size2;
151 change(z2,rank[size2],1);
152 ansquery(z1,rank[size2]);
153 }
154 printf(LL \n,anssize2);
155 }
156
157 return 0;
158 } 第二题 最暴力的dp很好做…………但是会T…………正确的做法要用stirling数进行优化…………但是我不会……………… (暂无 第三题 这题更不会了…………只知道是树链剖分套动态树…………以后有时间的时候再来说这道题吧……………… 暂无 Day 7: 第一题 这题很水我们设定一个参数t将度数大于t的设为大点将剩下的点设为小点。然后我们对大点小点分开做每次采用不同的方法暴力就行了。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includecmath5 #includealgorithm6 7 using namespace std;8 9 #ifdef unix10 #define LL %lld11 #else12 #define LL %I64d13 #endif14 15 const int maxn100010;16 const int maxm100010;17 18 int n,m,q,en,l,bigp[maxn],col[maxn],in[maxn];19 20 long long sum[2][2],cost[maxn][2];21 22 bool tag[maxn];23 24 char s[8];25 26 struct edge27 {28 int e;29 long long d;30 edge *next;31 }*v[maxn],ed[maxm1];32 33 struct edg34 {35 int s,e;36 long long d;37 bool operator(const edg a)const38 {39 return sa.s ea.e;40 }41 bool operator(const edg a)const42 {43 if (sa.s) return ea.e;44 else return sa.s;45 }46 }e[maxm];47 48 void add_edge(int s,int e,long long d)49 {50 en;51 ed[en].nextv[s];v[s]eden;v[s]-ee;v[s]-dd;52 }53 54 int main()55 {56 scanf(%d%d,n,m);57 for (int a1;an;a)58 scanf(%d,col[a]);59 for (int a1;am;a)60 {61 scanf(%d%d LL,e[a].s,e[a].e,e[a].d);62 if (e[a].se[a].e) swap(e[a].s,e[a].e);63 if (e[a].s0) printf(%d\n,a);64 }65 sort(e1,em1);66 int last1;67 for (int a2;am;a)68 if (e[a]e[last]) e[last].de[a].d,tag[a]true;69 else lasta;70 for (int a1;am;a)71 if (!tag[a]) in[e[a].s],in[e[a].e];72 int maxsize(int)exp(log(n)*2/3);73 //printf(%d\n,maxsize);74 for (int a1;am;a)75 if (!tag[a])76 {77 // printf(%d %d %I64d\n,e[a].s,e[a].e,e[a].d);78 if (in[e[a].s]maxsize)79 {80 add_edge(e[a].e,e[a].s,e[a].d);81 if (in[e[a].e]maxsize) 82 {83 add_edge(e[a].s,e[a].e,e[a].d);84 sum[min(col[e[a].s],col[e[a].e])][max(col[e[a].s],col[e[a].e])]e[a].d;85 }86 else cost[e[a].s][col[e[a].e]]e[a].d;87 }88 else89 {90 add_edge(e[a].s,e[a].e,e[a].d);91 if (in[e[a].e]maxsize) cost[e[a].e][col[e[a].s]]e[a].d;92 else93 {94 add_edge(e[a].e,e[a].s,e[a].d);95 sum[min(col[e[a].s],col[e[a].e])][max(col[e[a].s],col[e[a].e])]e[a].d;96 }97 }98 }99 for (int a1;an;a)
100 if (in[a]maxsize)
101 {
102 l;
103 bigp[l]a;
104 }
105 //printf(%I64d %I64d %I64d\n,sum[0][0],sum[0][1],sum[1][1]);
106 //for (int a1;an;a)
107 // printf(%I64d %I64d\n,cost[a][0],cost[a][1]);
108 scanf(%d,q);
109 for (int a1;aq;a)
110 {
111 scanf(%s,s);
112 if (s[0]A)
113 {
114 int c1,c2;
115 scanf(%d%d,c1,c2);
116 long long anssum[min(c1,c2)][max(c1,c2)];
117 for (int b1;bl;b)
118 {
119 int newcc1c2-col[bigp[b]];
120 if (newc0 || newc1) anscost[bigp[b]][newc];
121 }
122 printf(LL \n,ans);
123 }
124 else
125 {
126 int p;
127 scanf(%d,p);
128 if (in[p]maxsize)
129 {
130 for (edge *ev[p];e;ee-next)
131 {
132 sum[min(col[p],col[e-e])][max(col[p],col[e-e])]-e-d;
133 sum[min(col[p]^1,col[e-e])][max(col[p]^1,col[e-e])]e-d;
134 }
135 }
136 else
137 {
138 for (edge *ev[p];e;ee-next)
139 if (in[e-e]maxsize)
140 {
141 cost[e-e][col[p]]-e-d;
142 cost[e-e][col[p]^1]e-d;
143 }
144 else
145 {
146 sum[min(col[p],col[e-e])][max(col[p],col[e-e])]-e-d;
147 sum[min(col[p]^1,col[e-e])][max(col[p]^1,col[e-e])]e-d;
148 }
149 }
150 col[p]^1;
151 }
152 }
153
154 return 0;
155 } 第二题 首先解决周长为n的三角形个数有多少用f(n)表示考虑用a、b、c表示三条边并且有abc那么考虑以下两种情况 1、bc那么这个时候abc可以直接算出答案。 2、bc那么这个时候一定有abc1所以可以利用f(n-1)的值推过来在算一下abc1的情况就行了。 然后考虑用g(n)表示周长为n且三边gcd为1的三角形个数那么考虑排除gcd不为1的情况这个只需要枚举其gcd为多少然后减去相应的值即可。 然后考虑我们需要算出相似的组数那么考虑所有的相似三角形一定都是基于一个周长然后乘上了某个值那么我们只需要枚举这个基础周长然后利用组合公式算一算就行了。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includealgorithm5 6 using namespace std;7 8 const int maxn5000010;9 const int mo1000000007;
10
11 int n,cnt,f[maxn],er[maxn],divisor[maxn];
12
13 #define inc(a,b) ab,(amo ? a-mo : 0)
14
15 int main()
16 {
17 scanf(%d,n);
18 for (int a2;an;a)
19 f[a]f[a-2],inc(f[a],a/3-a/4);
20 for (int a1;a*an;a)
21 if (n % a0)
22 {
23 cnt;
24 divisor[cnt]a;
25 if (a*a!n)
26 {
27 cnt;
28 divisor[cnt]n/a;
29 }
30 }
31 sort(divisor1,divisorcnt1);
32 for (int a1;acnt;a)
33 for (int b1;ba;b)
34 if (divisor[a] % divisor[b]0) inc(f[divisor[a]],mo-f[divisor[b]]);
35 er[0]1;
36 for (int a1;an;a)
37 er[a]er[a-1],inc(er[a],er[a-1]);
38 int ans0;
39 for (int a1;acnt;a)
40 inc(ans,(long long)f[divisor[a]]*er[n/divisor[a]-1]%mo);
41 printf(%d\n,ans);
42
43 return 0;
44 } 第三题 此题即为暴力。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 5 using namespace std;6 7 long long n;8 9 #ifdef unix
10 #define LL %lld
11 #else
12 #define LL %I64d
13 #endif
14
15 int main()
16 {
17
18 scanf(LL,n);
19 long long ans0,tmp0;
20 for (long long a1,v;a*a(vn/a);a,ans)
21 for (long long ba1;b*bv;b)
22 tmpn/(a*b)-b;
23 anstmp*6;
24 tmp0;
25 for (long long a1,v;(va*a)n;a)
26 {
27 tmpn/v;
28 if (a*an/a) tmp--;
29 }
30 anstmp*3;
31 printf(LL \n,ans);
32
33 return 0;
34 } Day 8 第一题 这题是大水题啊推一下然后把矩阵搞出来然后快速幂就行了。注意如果推出来的矩阵比较大需要压缩矩阵不然会T。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 5 using namespace std;6 7 #ifdef unix8 #define LL %lld9 #else
10 #define LL %I64d
11 #endif
12
13 #define inc(a,b) (ab,(amo ? a-mo : 0))
14
15 long long k,A,B,C,D,n,mo;
16
17 struct matrix
18 {
19 long long z[3][3];
20 matrix()
21 {
22 memset(z,0,sizeof(z));
23 }
24 void init()
25 {
26 memset(z,0,sizeof(z));
27 }
28 matrix operator*(const matrix a)const
29 {
30 static matrix ans;
31 ans.init();
32 for (int b1;b2;b)
33 for (int c1;c2;c)
34 for (int d1;d2;d)
35 inc(ans.z[b][c],z[b][d]*a.z[d][c]%mo);
36 return ans;
37 }
38 }m1,m2;
39
40 void gedit(long long v)
41 {
42 v%mo;
43 if (v0) vmo;
44 }
45
46 long long mul(long long a,long long b)
47 {
48 long long ans1;
49 while (b)
50 {
51 if (b 1) ansans*a%mo;
52 aa*a%mo;
53 b1;
54 }
55 return ans;
56 }
57
58 int main()
59 {
60 int t;
61 scanf(%d,t);
62 for (int p1;pt;p)
63 {
64 scanf(LL LL LL LL LL LL LL,k,A,B,C,D,n,mo);
65 gedit(k);
66 gedit(A);
67 gedit(B);
68 gedit(C);
69 gedit(D);
70 if (n0) printf(LL \n,k);
71 else
72 {
73 n--;
74 m1.init();m2.init();
75 m1.z[1][1]A;m1.z[1][2]C;
76 m1.z[2][1]B;m1.z[2][2]D;
77 m2m1;
78 while (n)
79 {
80 if (n1) m1m1*m2;
81 m2m2*m2;
82 n1;
83 }
84 long long up(m1.z[1][1]*k%mom1.z[2][1])%mo;
85 long long down(m1.z[1][2]*k%mom1.z[2][2])%mo;
86 printf(LL \n,up*mul(down,mo-2)%mo);
87 }
88 }
89
90 return 0;
91 } 第二题 这题比较神我们从低位向高位进行dp没做到一位的时候进行一次排序将这些数按照后k位的大小进行排序。然后我们考虑我们要减去的那个数的后k位在哪个区间那么这样我们就可以算出减去这个数后会向高位借多少位那么每次枚举这个区间就行了。感觉这个思路简直太神了。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 5 using namespace std;6 7 #ifdef unix8 #define LL %lld9 #else
10 #define LL %I64d
11 #endif
12
13 const int maxn200010;
14
15 int n,delta[maxn];
16
17 long long f[70][maxn],z[maxn],sw[maxn];
18
19 int main()
20 {
21
22 scanf(%d,n);
23 for (int a1;an;a)
24 scanf(LL,z[a]);
25 f[0][0]1;
26 for (int a0;a63;a)
27 {
28 int l10,l20;
29 memset(delta,0,sizeof(delta));
30 for (int b1;bn;b)
31 if (((z[b]a)1)0) l2;
32 for (int b1;bn;b)
33 if (((z[b]a)1)0)
34 {
35 l1;
36 sw[l1]z[b];
37 delta[b]delta[b-1]1;
38 }
39 else
40 {
41 l2;
42 sw[l2]z[b];
43 delta[b]delta[b-1];
44 }
45 for (int b1;bn;b)
46 z[b]sw[b];
47 for (int b0;bn;b)
48 if (f[a][b])
49 {
50 if ((((n-delta[n])^b)1)0) f[a1][delta[b]]f[a][b];
51 if ((((n-delta[n])^(n-b))1)0) f[a1][delta[n]b-delta[b]]f[a][b];
52 }
53 }
54 for (int a2;an;a)
55 z[0]^z[a]-z[1];
56 if (z[0]0) f[64][0]--;
57 printf(LL \n,f[64][0]);
58
59 return 0;
60 } 第三题 把式子展开之后就可以发现只有一项特别囧的无法维护考试的时候我就暴力加一点优化结果有80分…………囧………… 如果我们把两个矩阵都写成一行的形式那么我们就可以发现我们要维护的那个东西就是很类似于高精度乘法的一个东西于是FFT优化即可但我不会写FFT…………囧……………… 暂无 Day 9 第一题 这题是搞笑的吧…………一开始我想用后缀数组加主席树来做…………发现不就是搞笑题吗………… 对模式串建一棵trie然后每个结点上记录有哪些编号的串能够到达这里看起来这东西很大其实空间和时间复杂度都是O(n)的然后对于每一个询问串暴力走就行了。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includealgorithm5 #includevector6 7 using namespace std;8 9 const int maxn100010;
10
11 int n,m,z[maxn];
12
13 char s[maxn];
14
15 struct node
16 {
17 node *next[26];
18 vectorint id;
19 node()
20 {
21 memset(next,0,sizeof(next));
22 }
23 }*root,*p,wmt[maxn],*wmtwmtwmt;
24
25 node *newnode()
26 {
27 return wmtwmt;
28 }
29
30 bool cmp(int a,int b)
31 {
32 return z[a]z[b];
33 }
34
35 void insert(int idx)
36 {
37 scanf(%s,s);
38 int lstrlen(s);
39 proot;
40 for (int a0;al;a)
41 {
42 if (p-next[s[a]-a]NULL) p-next[s[a]-a]newnode();
43 pp-next[s[a]-a];
44 if (!p-id.size() || p-id.back()!idx) p-id.push_back(idx);
45 }
46 }
47
48 void dfs(node *p)
49 {
50 sort(p-id.begin(),p-id.end(),cmp);
51 for (int a0;a26;a)
52 if (p-next[a]) dfs(p-next[a]);
53 }
54
55 void query()
56 {
57 int k;
58 scanf(%d%s,k,s);
59 int lstrlen(s);
60 proot;
61 for (int a0;al;a)
62 {
63 if (p-next[s[a]-a]NULL)
64 {
65 printf(0\n);
66 return;
67 }
68 pp-next[s[a]-a];
69 }
70 printf(%d ,(int)p-id.size());
71 int uppermin(k,(int)p-id.size());
72 for (int a0;aupper;a)
73 printf(%d ,p-id[a]-1);
74 printf(\n);
75 }
76
77 int main()
78 {
79
80 scanf(%d%d,n,m);
81 rootnewnode();
82 for (int a1;an;a)
83 {
84 scanf(%d,z[a]);
85 int num;
86 scanf(%d,num);
87 for (int b1;bnum;b)
88 insert(a);
89 }
90 dfs(root);
91 for (int a1;am;a)
92 query();
93
94 return 0;
95 } 第二题 水DP先算出到每个点不删边的答案然后枚举删掉哪条边然后算出答案即可。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includealgorithm5 #includecmath6 7 using namespace std;8 9 const int maxn10010;
10 const int maxm100010;
11
12 int n,m,en,l,z[maxn],sum[maxn],in[maxn];
13
14 long double f[maxn],p[maxn];
15
16 struct edge
17 {
18 int e,d;
19 edge *next;
20 }*v[maxn],ed[maxm];
21
22 void add_edge(int s,int e,int d)
23 {
24 en;
25 ed[en].nextv[s];v[s]eden;v[s]-ee;v[s]-dd;
26 }
27
28 int main()
29 {
30 scanf(%d%d,n,m);
31 for (int a1;am;a)
32 {
33 int s,e,d;
34 scanf(%d%d%d,s,e,d);
35 s;e;
36 add_edge(s,e,d);
37 sum[s]d;
38 in[e];
39 }
40 for (int a1;an;a)
41 if (!in[a])
42 {
43 l;
44 z[l]a;
45 }
46 for (int a1;an;a)
47 for (edge *ev[z[a]];e;ee-next)
48 {
49 in[e-e]--;
50 if (!in[e-e])
51 {
52 l;
53 z[l]e-e;
54 }
55 }
56 p[1]1;
57 for (int a1;an;a)
58 for (edge *ev[z[a]];e;ee-next)
59 p[e-e]p[z[a]]*e-d/sum[z[a]];
60 for (int an;a1;a--)
61 for (edge *ev[z[a]];e;ee-next)
62 f[z[a]](f[e-e]1)*e-d/sum[z[a]];
63 long double ansf[1];
64 for (int a1;an;a)
65 for (edge *ev[z[a]];e;ee-next)
66 if (e-d!sum[z[a]]) ansmax(ans,f[1]p[z[a]]*((f[z[a]]-(f[e-e]1)*e-d/sum[z[a]])*sum[z[a]]/(sum[z[a]]-e-d)-f[z[a]]));
67 printf(%.6lf\n,(double)ans);
68
69 return 0;
70 } 第三题 这题怎么乱搞都行啊………………不过数据好像有问题…………囧………… 暂无 Day 10 第一题 考虑从每个点开始会有四个方向我们只考虑其中某一个方向比如说朝右下这个时候我们可以发现这条直线上的xy值是不变的那么我们只需要按照xy为第一关键字排个序就能知道每个点朝右下走下一次会到哪一个点上去那么对每个方向都做一个这样的处理。然后每次我们从每个点暴力向外走由于每个点最多只会被经过两次那么暴力走的这一块的复杂度是O(n)的。 暂无 第二题 考虑最上面、最下面、最左面、左右面右4个顶点而我们只有三个正方形那么一定会有一个正方形覆盖到整个大矩形的一个角。有了这个性质之后就很好做了我们首先二分答案然后枚举第一个矩形放在了哪个角然后剩下两个矩形一样的做法就可以了。 View Code 1 #includecstdio2 #includecstdlib3 #includecstring4 #includealgorithm5 6 using namespace std;7 8 const int maxn100010;9 const int INF0x3f3f3f3f;
10
11 int n,minxINF,minyINF,maxx-INF,maxy-INF,x[maxn],y[maxn],in[maxn];
12
13 bool inside(int x1,int y1,int r,int x2,int y2)
14 {
15 return (x2x1) (x2x1r) (y2y1) (y2y1r);
16 }
17
18 bool check_tap2(int xx,int yy,int r)
19 {
20 for (int a1;an;a)
21 if (inside(xx,yy,r,x[a],y[a])) in[a];
22 int x1INF,x2-INF,y1INF,y2-INF;
23 for (int a1;an;a)
24 if (!in[a])
25 {
26 x1min(x1,x[a]);
27 y1min(y1,y[a]);
28 x2max(x2,x[a]);
29 y2max(y2,y[a]);
30 }
31 for (int a1;an;a)
32 if (inside(xx,yy,r,x[a],y[a])) in[a]--;
33 if (x2-x1r y2-y1r) return true;
34 return false;
35 }
36
37 bool check_tap(int xx,int yy,int r)
38 {
39 for (int a1;an;a)
40 if (inside(xx,yy,r,x[a],y[a])) in[a];
41 int x1INF,x2-INF,y1INF,y2-INF;
42 for (int a1;an;a)
43 if (!in[a])
44 {
45 x1min(x1,x[a]);
46 y1min(y1,y[a]);
47 x2max(x2,x[a]);
48 y2max(y2,y[a]);
49 }
50 if (x1INF)
51 {
52 for (int a1;an;a)
53 if (inside(xx,yy,r,x[a],y[a])) in[a]--;
54 return true;
55 }
56 bool ablecheck_tap2(x1,y1,r) || check_tap2(x1,y2-r,r) || check_tap2(x2-r,y1,r) || check_tap2(x2-r,y2-r,r);
57 for (int a1;an;a)
58 if (inside(xx,yy,r,x[a],y[a])) in[a]--;
59 return able;
60 }
61
62 bool check(int r)
63 {
64 if (check_tap(minx,miny,r) || check_tap(minx,maxy-r,r) || check_tap(maxx-r,miny,r) || check_tap(maxx-r,maxy-r,r)) return true;
65 else return false;
66 }
67
68 int main()
69 {
70 scanf(%d,n);
71 for (int a1;an;a)
72 {
73 scanf(%d%d,x[a],y[a]);
74 minxmin(minx,x[a]);
75 minymin(miny,y[a]);
76 maxxmax(maxx,x[a]);
77 maxymax(maxy,y[a]);
78 }
79 int l0,r1000000000;
80 while (l1!r)
81 {
82 int m(lr)1;
83 if (check(m)) rm;
84 else lm;
85 }
86 printf(%d\n,r);
87
88 return 0;
89 } 第三题 考虑会出现冲突的情况只有s1s2 and t1s2 and t1t2这一种情况那么我们………………………………………………………………………………………………………… 暂无 关于有部分还没有的东西以后会慢慢更新的………… 转载于:https://www.cnblogs.com/zhonghaoxi/archive/2012/12/20/2827208.html