Lollipop:
如果X可行,那么X-2也一定可行。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4
5 using namespace std;
6
7 const int maxn=1000010;
8 const int INF=0x3f3f3f3f;
9
10 int n,m,z[maxn],ans[maxn<<1][2];
11
12 char s[maxn];
13
14 int main()
15 {
16 freopen("lollipop.in","r",stdin);
17 freopen("lollipop.out","w",stdout);
18
19 scanf("%d%d",&n,&m);
20 scanf("%s",s+1);
21 for (int a=1;a<=n;a++)
22 z[a]=(s[a]=='T' ? 2 : 1);
23 int left,right,lv=INF,rv=INF;
24 int sum=0;
25 for (int a=1;a<=n;a++)
26 {
27 sum+=z[a];
28 if (sum&1)
29 {
30 left=a;
31 lv=sum;
32 break;
33 }
34 }
35 sum=0;
36 for (int a=n;a>=1;a--)
37 {
38 sum+=z[a];
39 if (sum&1)
40 {
41 right=a;
42 rv=sum;
43 break;
44 }
45 }
46 sum=0;
47 for (int a=1;a<=n;a++)
48 sum+=z[a];
49 int sx=sum;
50 int nowl=1,nowr=n;
51 ans[sum][0]=1;ans[sum][1]=n;
52 while (sum>0)
53 {
54 if (z[nowl]==2) nowl++;
55 else
56 {
57 if (z[nowr]==2) nowr--;
58 else nowl++,nowr--;
59 }
60 sum-=2;
61 if (sum>0) ans[sum][0]=nowl,ans[sum][1]=nowr;
62 }
63 sum=sx;
64 if (lv<rv) nowl=left+1,nowr=n,sum-=lv;
65 else nowl=1,nowr=right-1,sum-=rv;
66 if (sum>0) ans[sum][0]=nowl,ans[sum][1]=nowr;
67 while (sum>0)
68 {
69 if (z[nowl]==2) nowl++;
70 else
71 {
72 if (z[nowr]==2) nowr--;
73 else nowl++,nowr--;
74 }
75 sum-=2;
76 if (sum>0) ans[sum][0]=nowl,ans[sum][1]=nowr;
77 }
78 for (int a=1;a<=m;a++)
79 {
80 int v;
81 scanf("%d",&v);
82 if (ans[v][0]) printf("%d %d
",ans[v][0],ans[v][1]);
83 else printf("NIE
");
84 }
85
86 return 0;
87 }
Garbage:
过不了……RE……20……
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4
5 using namespace std;
6
7 const int maxn=100010;
8 const int maxm=2000010;
9
10 int n,m,en,ans,p,res[maxn*5],next[maxm],pre[maxm],first[maxn],end[maxm],size[maxn],op[maxm];
11
12 void add_edge(int s,int e)
13 {
14 en++;
15 next[en]=first[s];pre[first[s]]=en;end[en]=e;first[s]=en;
16 en++;
17 next[en]=first[e];pre[first[e]]=en;end[en]=s;first[e]=en;
18 op[first[s]]=first[e];op[first[e]]=first[s];
19 size[s]++;size[e]++;
20 }
21
22 bool dfs(int now,int start,int d)
23 {
24 for (int a=first[now];a;a=next[a])
25 {
26 int b=op[a];
27 pre[next[a]]=pre[a];
28 next[pre[a]]=next[a];
29 int fp1=first[now];
30 if (a==first[now]) first[now]=next[a];
31 pre[next[b]]=pre[b];
32 next[pre[b]]=next[b];
33 int fp2=first[end[a]];
34 if (b==first[end[a]]) first[end[a]]=next[b];
35 size[now]--;size[end[a]]--;
36 if (end[a]==start)
37 {
38 res[p]=d;
39 res[p+d+1]=start;
40 p+=d+2;
41 return true;
42 }
43 res[p+d+1]=end[a];
44 if (dfs(end[a],start,d+1)) return true;
45 pre[next[a]]=next[pre[a]]=a;
46 first[now]=fp1;
47 pre[next[b]]=next[pre[b]]=b;
48 first[end[a]]=fp2;
49 size[now]++;size[end[a]]++;
50 }
51 return false;
52 }
53
54 int main()
55 {
56 freopen("garbage.in","r",stdin);
57 freopen("garbage.out","w",stdout);
58
59 scanf("%d%d",&n,&m);
60 for (int a=1;a<=m;a++)
61 {
62 int s,e,v1,v2;
63 scanf("%d%d%d%d",&s,&e,&v1,&v2);
64 if (v1!=v2) add_edge(s,e);
65 }
66 for (int a=1;a<=n;a++)
67 if (size[a]%2==1)
68 {
69 printf("NIE
");
70 return 0;
71 }
72 for (int a=1;a<=n;a++)
73 {
74 while (size[a])
75 {
76 ans++;
77 res[p+1]=a;
78 dfs(a,a,1);
79 }
80 }
81 printf("%d
",ans);
82 int p=0;
83 for (int a=1;a<=ans;a++)
84 {
85 printf("%d ",res[p]);
86 for (int b=1;b<=res[p]+1;b++)
87 printf("%d ",res[p+b]);
88 printf("
");
89 p=res[p]+p+2;
90 }
91
92 return 0;
93 }
Tree Rotations 2:
另外一个的大数据版本……令人sad的99……
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<cctype>
5 #include<algorithm>
6
7 using namespace std;
8
9 const int BUF_SIZE = 30;
10 char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1;
11
12 #define PTR_NEXT()
13 {
14 buf_s ++;
15 if (buf_s == buf_t)
16 {
17 buf_s = buf;
18 buf_t = buf + fread(buf, 1, BUF_SIZE, stdin);
19 }
20 }
21
22 #define readint(_n_)
23 {
24 while (*buf_s != '-' && !isdigit(*buf_s))
25 PTR_NEXT();
26 bool register _nega_ = false;
27 if (*buf_s == '-')
28 {
29 _nega_ = true;
30 PTR_NEXT();
31 }
32 int register _x_ = 0;
33 while (isdigit(*buf_s))
34 {
35 _x_ = _x_ * 10 + *buf_s - '0';
36 PTR_NEXT();
37 }
38 if (_nega_)
39 _x_ = -_x_;
40 (_n_) = (_x_);
41 }
42
43 #define update(x) z[x].size=z[z[x].l].size+z[z[x].r].size+1;
44
45 const int maxn=1000010;
46
47 int n,en,size,rx,l[maxn<<1],r[maxn<<1],value[maxn<<1],f[maxn<<1],q[maxn<<1],s[maxn<<1],root[maxn<<1];
48
49 struct node
50 {
51 int l,r,v,size;
52 node()
53 {
54 l=r=v=size=0;
55 }
56 }z[maxn];
57
58 struct edge
59 {
60 int e;
61 edge *next;
62 }*v[maxn<<1],ed[maxn<<1];
63
64 inline void add_edge(int s,int e)
65 {
66 en++;
67 ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;
68 }
69
70 inline void rot_l(int &x)
71 {
72 int y=z[x].r;
73 z[x].r=z[y].l;
74 z[y].l=x;
75 update(x);
76 update(y);
77 x=y;
78 }
79
80 inline void rot_r(int &x)
81 {
82 int y=z[x].l;
83 z[x].l=z[y].r;
84 z[y].r=x;
85 update(x);
86 update(y);
87 x=y;
88 }
89
90 inline void maintain(int &x,bool flag)
91 {
92 if (!x) return;
93 if (flag)
94 {
95 if (z[z[x].r].size<z[z[z[x].l].l].size) rot_r(x);
96 else
97 {
98 if (z[z[x].r].size<z[z[z[x].l].r].size)
99 {
100 rot_l(z[x].l);
101 rot_r(x);
102 }
103 else return;
104 }
105 }
106 else
107 {
108 if (z[z[x].l].size<z[z[z[x].r].r].size) rot_l(x);
109 else
110 {
111 if (z[z[x].l].size<z[z[z[x].r].l].size)
112 {
113 rot_r(z[x].r);
114 rot_l(x);
115 }
116 else return;
117 }
118 }
119 maintain(z[x].l,1);
120 maintain(z[x].r,0);
121 maintain(x,1);
122 maintain(x,0);
123 }
124
125 inline void insert(int &x,int v)
126 {
127 if (!x)
128 {
129 x=++size;
130 z[x].v=v;
131 z[x].size=1;
132 z[x].l=z[x].r=0;
133 }
134 else
135 {
136 z[x].size++;
137 if (v<z[x].v) insert(z[x].l,v);
138 else insert(z[x].r,v);
139 maintain(x,v<z[x].v);
140 }
141 }
142
143 inline void insert(int &x,int v,int px)
144 {
145 if (!x)
146 {
147 x=px;
148 z[x].v=v;
149 z[x].size=1;
150 z[x].l=z[x].r=0;
151 }
152 else
153 {
154 z[x].size++;
155 if (v<z[x].v) insert(z[x].l,v,px);
156 else insert(z[x].r,v,px);
157 maintain(x,v<z[x].v);
158 }
159 }
160
161 inline int del(int &x,int v)
162 {
163 z[x].size--;
164 if (v==z[x].v || (v<z[x].v && !z[x].l) || (v>z[x].v && !z[x].r))
165 {
166 int ans=z[x].v;
167 if (!z[x].l || !z[x].r) x=z[x].l+z[x].r;
168 else
169 {
170 z[x].v=del(z[x].r,0);
171 maintain(x,0);
172 }
173 return ans;
174 }
175 else
176 {
177 int ans;
178 if (v<z[x].v) ans=del(z[x].l,v);
179 else ans=del(z[x].r,v);
180 maintain(x,v>=z[x].v);
181 }
182 }
183
184 inline int query(int p,int v)
185 {
186 int ans=0;
187 while (p)
188 {
189 if (z[p].v<v) ans+=z[z[p].l].size+1,p=z[p].r;
190 else p=z[p].l;
191 }
192 return ans;
193 }
194
195 inline long long solve(int p,int r)
196 {
197 long long v=query(r,z[p].v);
198 if (z[p].l) v+=solve(z[p].l,r);
199 if (z[p].r) v+=solve(z[p].r,r);
200 return v;
201 }
202
203 inline void add(int p)
204 {
205 if (z[p].l) add(z[p].l);
206 if (z[p].r) add(z[p].r);
207 insert(rx,z[p].v,p);
208 }
209
210 int main()
211 {
212 //freopen("tree2.in","r",stdin);
213 //freopen("tree2.out","w",stdout);
214
215 readint(n);
216 int p=1,cnt=1;
217 while (p)
218 {
219 if (s[p]==0)
220 {
221 readint(value[p]);
222 s[p]++;
223 if (value[p]) p=f[p];
224 }
225 else
226 {
227 if (s[p]==1)
228 {
229 l[p]=++cnt;
230 add_edge(p,cnt);
231 f[cnt]=p;
232 s[p]++;
233 p=l[p];
234 }
235 else
236 {
237 if (s[p]==2)
238 {
239 r[p]=++cnt;
240 add_edge(p,cnt);
241 f[cnt]=p;
242 s[p]++;
243 p=r[p];
244 }
245 else p=f[p];
246 }
247 }
248 }
249 int front=1,tail=1;
250 q[1]=1;
251 for (;front<=tail;)
252 {
253 int now=q[front++];
254 for (edge *e=v[now];e;e=e->next)
255 q[++tail]=e->e;
256 }
257 long long ans=0;
258 for (int a=tail;a>=1;a--)
259 {
260 int now=q[a];
261 if (value[now]) insert(root[now],value[now]);
262 else
263 {
264 if (z[root[l[now]]].size>z[root[r[now]]].size) swap(l[now],r[now]);
265 root[now]=root[r[now]];
266 long long v1=solve(root[l[now]],root[now]);
267 long long v2=(long long)z[root[l[now]]].size*z[root[now]].size-v1;
268 ans+=min(v1,v2);
269 rx=root[now];
270 add(root[l[now]]);
271 root[now]=rx;
272 }
273 }
274 printf("%lld
",ans);
275
276 return 0;
277 }
Tree Rotations:
启发式合并。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<algorithm>
5
6 using namespace std;
7
8 const int maxn=200010;
9
10 int n,en,size,l[maxn<<1],r[maxn<<1],value[maxn<<1],f[maxn<<1],q[maxn<<1],s[maxn<<1],root[maxn<<1];
11
12 struct node
13 {
14 int l,r,v,size;
15 node()
16 {
17 l=r=v=size=0;
18 }
19 }z[maxn];
20
21 struct edge
22 {
23 int e;
24 edge *next;
25 }*v[maxn<<1],ed[maxn<<1];
26
27 void add_edge(int s,int e)
28 {
29 en++;
30 ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;
31 }
32
33 void update(int rt)
34 {
35 z[rt].size=z[z[rt].l].size+z[z[rt].r].size+1;
36 }
37
38 void rot_l(int &x)
39 {
40 int y=z[x].r;
41 z[x].r=z[y].l;
42 z[y].l=x;
43 update(x);
44 update(y);
45 x=y;
46 }
47
48 void rot_r(int &x)
49 {
50 int y=z[x].l;
51 z[x].l=z[y].r;
52 z[y].r=x;
53 update(x);
54 update(y);
55 x=y;
56 }
57
58 void maintain(int &x,bool flag)
59 {
60 if (!x) return;
61 if (flag)
62 {
63 if (z[z[x].r].size<z[z[z[x].l].l].size) rot_r(x);
64 else
65 {
66 if (z[z[x].r].size<z[z[z[x].l].r].size)
67 {
68 rot_l(z[x].l);
69 rot_r(x);
70 }
71 else return;
72 }
73 }
74 else
75 {
76 if (z[z[x].l].size<z[z[z[x].r].r].size) rot_l(x);
77 else
78 {
79 if (z[z[x].l].size<z[z[z[x].r].l].size)
80 {
81 rot_r(z[x].r);
82 rot_l(x);
83 }
84 else return;
85 }
86 }
87 maintain(z[x].l,1);
88 maintain(z[x].r,0);
89 maintain(x,1);
90 maintain(x,0);
91 }
92
93 void insert(int &x,int v)
94 {
95 if (!x)
96 {
97 x=++size;
98 z[x].v=v;
99 z[x].size=1;
100 z[x].l=z[x].r=0;
101 }
102 else
103 {
104 z[x].size++;
105 if (v<z[x].v) insert(z[x].l,v);
106 else insert(z[x].r,v);
107 maintain(x,v<z[x].v);
108 }
109 }
110
111 void insert(int &x,int v,int px)
112 {
113 if (!x)
114 {
115 x=px;
116 z[x].v=v;
117 z[x].size=1;
118 z[x].l=z[x].r=0;
119 }
120 else
121 {
122 z[x].size++;
123 if (v<z[x].v) insert(z[x].l,v,px);
124 else insert(z[x].r,v,px);
125 maintain(x,v<z[x].v);
126 }
127 }
128
129 int del(int &x,int v)
130 {
131 z[x].size--;
132 if (v==z[x].v || (v<z[x].v && !z[x].l) || (v>z[x].v && !z[x].r))
133 {
134 int ans=z[x].v;
135 if (!z[x].l || !z[x].r) x=z[x].l+z[x].r;
136 else
137 {
138 z[x].v=del(z[x].r,0);
139 maintain(x,0);
140 }
141 return ans;
142 }
143 else
144 {
145 int ans;
146 if (v<z[x].v) ans=del(z[x].l,v);
147 else ans=del(z[x].r,v);
148 maintain(x,v>=z[x].v);
149 }
150 }
151
152 int query(int p,int v)
153 {
154 int ans=0;
155 while (p)
156 {
157 if (z[p].v<v) ans+=z[z[p].l].size+1,p=z[p].r;
158 else p=z[p].l;
159 }
160 return ans;
161 }
162
163 long long solve(int p,int r)
164 {
165 long long v=query(r,z[p].v);
166 if (z[p].l) v+=solve(z[p].l,r);
167 if (z[p].r) v+=solve(z[p].r,r);
168 return v;
169 }
170
171 void add(int p,int &r)
172 {
173 if (z[p].l) add(z[p].l,r);
174 if (z[p].r) add(z[p].r,r);
175 insert(r,z[p].v,p);
176 }
177
178 int main()
179 {
180 freopen("tree1.in","r",stdin);
181 freopen("tree1.out","w",stdout);
182
183 scanf("%d",&n);
184 int p=1,cnt=1;
185 while (p)
186 {
187 if (s[p]==0)
188 {
189 scanf("%d",&value[p]);
190 s[p]++;
191 if (value[p]) p=f[p];
192 }
193 else
194 {
195 if (s[p]==1)
196 {
197 l[p]=++cnt;
198 add_edge(p,cnt);
199 f[cnt]=p;
200 s[p]++;
201 p=l[p];
202 }
203 else
204 {
205 if (s[p]==2)
206 {
207 r[p]=++cnt;
208 add_edge(p,cnt);
209 f[cnt]=p;
210 s[p]++;
211 p=r[p];
212 }
213 else p=f[p];
214 }
215 }
216 }
217 int front=1,tail=1;
218 q[1]=1;
219 for (;front<=tail;)
220 {
221 int now=q[front++];
222 for (edge *e=v[now];e;e=e->next)
223 q[++tail]=e->e;
224 }
225 long long ans=0;
226 for (int a=tail;a>=1;a--)
227 {
228 int now=q[a];
229 if (value[now]) insert(root[now],value[now]);
230 else
231 {
232 if (z[root[l[now]]].size>z[root[r[now]]].size) swap(l[now],r[now]);
233 root[now]=root[r[now]];
234 long long v1=solve(root[l[now]],root[now]);
235 long long v2=(long long)z[root[l[now]]].size*z[root[now]].size-v1;
236 ans+=min(v1,v2);
237 add(root[l[now]],root[now]);
238 }
239 }
240 printf("%lld
",ans);
241
242 return 0;
243 }
Temperature:
单调栈直接维护。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<cctype>
5 #include<algorithm>
6
7 using namespace std;
8
9 const int BUF_SIZE = 30;
10 char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1;
11
12 #define PTR_NEXT()
13 {
14 buf_s ++;
15 if (buf_s == buf_t)
16 {
17 buf_s = buf;
18 buf_t = buf + fread(buf, 1, BUF_SIZE, stdin);
19 }
20 }
21
22 #define readint(_n_)
23 {
24 while (*buf_s != '-' && !isdigit(*buf_s))
25 PTR_NEXT();
26 bool register _nega_ = false;
27 if (*buf_s == '-')
28 {
29 _nega_ = true;
30 PTR_NEXT();
31 }
32 int register _x_ = 0;
33 while (isdigit(*buf_s))
34 {
35 _x_ = _x_ * 10 + *buf_s - '0';
36 PTR_NEXT();
37 }
38 if (_nega_)
39 _x_ = -_x_;
40 (_n_) = (_x_);
41 }
42
43 const int maxn=1000010;
44
45 int n,m,q[maxn][2];
46
47 int main()
48 {
49 freopen("temperature.in","r",stdin);
50 freopen("temperature.out","w",stdout);
51
52 readint(n);
53 int l,r;
54 int front=1,tail=0;
55 int ans=1;
56 for (int a=1;a<=n;a++)
57 {
58 readint(l);
59 readint(r);
60 while (front<=tail && q[front][1]>r)
61 front++;
62 int p=a;
63 while (front<=tail && q[tail][1]<l)
64 p=q[tail--][0];
65 tail++;
66 q[tail][0]=p;
67 q[tail][1]=l;
68 ans=max(ans,a-q[front][0]+1);
69 }
70 printf("%d
",ans);
71
72 return 0;
73 }
Dynamite:
二分答案,然后从下往上必须放的时候就放。不知道哪里写错了,加了个随机化过掉的。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<cctype>
5 #include<algorithm>
6
7 using namespace std;
8
9 const int BUF_SIZE = 30;
10 char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1;
11
12 #define PTR_NEXT()
13 {
14 buf_s ++;
15 if (buf_s == buf_t)
16 {
17 buf_s = buf;
18 buf_t = buf + fread(buf, 1, BUF_SIZE, stdin);
19 }
20 }
21
22 #define readint(_n_)
23 {
24 while (*buf_s != '-' && !isdigit(*buf_s))
25 PTR_NEXT();
26 bool register _nega_ = false;
27 if (*buf_s == '-')
28 {
29 _nega_ = true;
30 PTR_NEXT();
31 }
32 int register _x_ = 0;
33 while (isdigit(*buf_s))
34 {
35 _x_ = _x_ * 10 + *buf_s - '0';
36 PTR_NEXT();
37 }
38 if (_nega_)
39 _x_ = -_x_;
40 (_n_) = (_x_);
41 }
42
43 const int maxn=300010;
44
45 int n,m,en,q[maxn],max_dist[maxn],cover[maxn],bomb[maxn],f[maxn];
46
47 struct edge
48 {
49 int e;
50 edge *next;
51 }*v[maxn],ed[maxn<<1];
52
53 void add_edge(int s,int e)
54 {
55 en++;
56 ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;
57 }
58
59 bool check(int d)
60 {
61 int cnt=0;
62 memset(max_dist,-1,sizeof(max_dist));
63 memset(cover,0,sizeof(cover));
64 for (int a=n;a>=1;a--)
65 {
66 int now=q[a];
67 if (max_dist[now]==d || (now==q[1] && (max_dist[now]!=-1 || (bomb[now] && !cover[now]))))
68 {
69 cnt++;
70 if (cnt>m) return false;
71 cover[f[now]]=max(cover[f[now]],d);
72 }
73 else
74 {
75 cover[f[now]]=max(cover[f[now]],cover[now]-1);
76 if (bomb[now]) max_dist[now]=max(max_dist[now],0);
77 if (max_dist[now]<cover[now]) max_dist[now]=-1;
78 if (max_dist[now]!=-1) max_dist[f[now]]=max(max_dist[f[now]],max_dist[now]+1);
79 }
80 }
81 return true;
82 }
83
84 int main()
85 {
86 freopen("dynamite.in","r",stdin);
87 freopen("dynamite.out","w",stdout);
88
89 srand(1996061819960210ll);
90 readint(n);
91 readint(m);
92 int cnt=0;
93 for (int a=1;a<=n;a++)
94 {
95 readint(bomb[a]);
96 cnt+=bomb[a];
97 }
98 if (cnt<=m)
99 {
100 printf("0
");
101 return 0;
102 }
103 int s,e;
104 for (int a=1;a<n;a++)
105 {
106 readint(s);
107 readint(e);
108 add_edge(s,e);
109 add_edge(e,s);
110 }
111 int ans=n;
112 for (int a=1;a<=2;a++)
113 {
114 int front=1,tail=1;
115 q[1]=rand()%n+1;
116 for (int b=1;b<=n;b++)
117 f[b]=0;
118 for (;front<=tail;)
119 {
120 int now=q[front++];
121 for (edge *e=v[now];e;e=e->next)
122 if (e->e!=q[1] && !f[e->e])
123 {
124 f[e->e]=now;
125 q[++tail]=e->e;
126 }
127 }
128 int l=0,r=n;
129 while (l+1!=r)
130 {
131 int m=(l+r)>>1;
132 if (check(m)) r=m;
133 else l=m;
134 }
135 ans=min(ans,r);
136 }
137 printf("%d
",ans);
138
139 return 0;
140 }
Party:
每次删除两个不相连的点。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4
5 using namespace std;
6
7 const int maxn=3010;
8
9 int n,m;
10
11 bool con[maxn][maxn],del[maxn];
12
13 int main()
14 {
15 freopen("party.in","r",stdin);
16 freopen("party.out","w",stdout);
17
18 scanf("%d%d",&n,&m);
19 for (int a=1;a<=m;a++)
20 {
21 int s,e;
22 scanf("%d%d",&s,&e);
23 con[s][e]=con[e][s]=true;
24 }
25 for (int a=1,b=n/3;a<=n && b>0;a++)
26 if (!del[a])
27 {
28 for (int c=a+1;c<=n;c++)
29 if (!del[c] && !con[a][c])
30 {
31 b--;
32 del[a]=del[c]=true;
33 break;
34 }
35 }
36 for (int a=1,b=n/3;b>0;a++)
37 if (!del[a])
38 {
39 printf("%d",a);
40 b--;
41 if (b) printf(" ");
42 else printf("
");
43 }
44
45 return 0;
46 }
Inspection:
简单的树形DP。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<cctype>
5 #include<algorithm>
6
7 using namespace std;
8
9 const int BUF_SIZE = 30;
10 char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1;
11
12 #define PTR_NEXT()
13 {
14 buf_s ++;
15 if (buf_s == buf_t)
16 {
17 buf_s = buf;
18 buf_t = buf + fread(buf, 1, BUF_SIZE, stdin);
19 }
20 }
21
22 #define readint(_n_)
23 {
24 while (*buf_s != '-' && !isdigit(*buf_s))
25 PTR_NEXT();
26 bool register _nega_ = false;
27 if (*buf_s == '-')
28 {
29 _nega_ = true;
30 PTR_NEXT();
31 }
32 int register _x_ = 0;
33 while (isdigit(*buf_s))
34 {
35 _x_ = _x_ * 10 + *buf_s - '0';
36 PTR_NEXT();
37 }
38 if (_nega_)
39 _x_ = -_x_;
40 (_n_) = (_x_);
41 }
42
43 const int maxn=1000010;
44
45 int n,en,q[maxn],f[maxn],f_max_dist[maxn],size[maxn],max_dist[maxn][2];
46
47 long long tot_dist[maxn],f_dist[maxn],res[maxn];
48
49 bool use[maxn];
50
51 struct edge
52 {
53 int e;
54 edge *next;
55 }*v[maxn],ed[maxn<<1];
56
57 void add_edge(int s,int e)
58 {
59 en++;
60 ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;
61 }
62
63 int main()
64 {
65 freopen("inspection.in","r",stdin);
66 freopen("inspection.out","w",stdout);
67
68 readint(n);
69 int s,e;
70 for (int a=1;a<n;a++)
71 {
72 readint(s);
73 readint(e);
74 add_edge(s,e);
75 add_edge(e,s);
76 }
77 int front=1,tail=1;
78 q[1]=1;
79 use[1]=true;
80 for (;front<=tail;)
81 {
82 int now=q[front++];
83 for (edge *e=v[now];e;e=e->next)
84 if (!use[e->e])
85 {
86 q[++tail]=e->e;
87 use[e->e]=true;
88 f[e->e]=now;
89 }
90 }
91 for (int a=n;a>=1;a--)
92 {
93 int now=q[a];
94 size[now]++;
95 size[f[now]]+=size[now];
96 tot_dist[f[now]]+=tot_dist[now]+size[now];
97 if (max_dist[now][0]+1>=max_dist[f[now]][0])
98 {
99 max_dist[f[now]][1]=max_dist[f[now]][0];
100 max_dist[f[now]][0]=max_dist[now][0]+1;
101 }
102 else
103 {
104 if (max_dist[now][0]+1>max_dist[f[now]][1]) max_dist[f[now]][1]=max_dist[now][0]+1;
105 }
106 }
107 for (int a=1;a<=n;a++)
108 {
109 int now=q[a];
110 long long value=f_dist[now]+tot_dist[now];
111 value<<=1;
112 int now_max_size=n-size[now];
113 int now_max_sizep=0;
114 int now_max_dist=f_max_dist[now];
115 int now_max_distp=0;
116 for (edge *e=v[now];e;e=e->next)
117 if (f[e->e]==now)
118 {
119 if (size[e->e]>now_max_size)
120 {
121 now_max_size=size[e->e];
122 now_max_sizep=e->e;
123 }
124 if (max_dist[e->e][0]+1>now_max_dist)
125 {
126 now_max_dist=max_dist[e->e][0]+1;
127 now_max_distp=e->e;
128 }
129 }
130 if (now_max_size*2>n-1)
131 {
132 if (now_max_size*2>n) value=-1;
133 else
134 {
135 if (now_max_sizep==0) value-=f_max_dist[now];
136 else value-=max_dist[now_max_sizep][0]+1;
137 }
138 }
139 else value-=now_max_dist;
140 res[now]=value;
141 for (edge *e=v[now];e;e=e->next)
142 if (f[e->e]==now)
143 {
144 int vx;
145 if (max_dist[e->e][0]+1==max_dist[now][0]) vx=max_dist[now][1];
146 else vx=max_dist[now][0];
147 f_max_dist[e->e]=max(f_max_dist[now],vx)+1;
148 f_dist[e->e]=f_dist[now]+tot_dist[now]-tot_dist[e->e]-size[e->e]+n-size[e->e];
149 }
150 }
151 for (int a=1;a<=n;a++)
152 printf("%lld
",res[a]);
153
154 return 0;
155 }
Meteors:
对询问分治,变为区间修改单点询问,注意爆long long以及卡常数等东西。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<cctype>
5 #include<algorithm>
6
7 using namespace std;
8
9 const int BUF_SIZE = 30;
10 char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1;
11
12 #define PTR_NEXT()
13 {
14 buf_s ++;
15 if (buf_s == buf_t)
16 {
17 buf_s = buf;
18 buf_t = buf + fread(buf, 1, BUF_SIZE, stdin);
19 }
20 }
21
22 #define readint(_n_)
23 {
24 while (*buf_s != '-' && !isdigit(*buf_s))
25 PTR_NEXT();
26 bool register _nega_ = false;
27 if (*buf_s == '-')
28 {
29 _nega_ = true;
30 PTR_NEXT();
31 }
32 int register _x_ = 0;
33 while (isdigit(*buf_s))
34 {
35 _x_ = _x_ * 10 + *buf_s - '0';
36 PTR_NEXT();
37 }
38 if (_nega_)
39 _x_ = -_x_;
40 (_n_) = (_x_);
41 }
42
43 #define lb(x) ((x)&(-(x)))
44
45 const int maxn=300010;
46
47 int n,m,k,en,l[maxn],r[maxn],mid[maxn],left[maxn],right[maxn],delta[maxn],need[maxn],z[maxn];
48
49 long long y[maxn];
50
51 struct edge
52 {
53 int e;
54 edge *next;
55 }*v[maxn],ed[maxn];
56
57 void add_edge(int s,int e)
58 {
59 en++;
60 ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;
61 }
62
63 bool cmp(int a,int b)
64 {
65 return mid[a]<mid[b];
66 }
67
68 void modify(int p,int d)
69 {
70 for (;p<=m;p+=lb(p))
71 y[p]+=d;
72 }
73
74 long long query(int p)
75 {
76 long long ans=0;
77 for (;p;p-=lb(p))
78 ans+=y[p];
79 return ans;
80 }
81
82 int main()
83 {
84 freopen("meteors.in","r",stdin);
85 freopen("meteors.out","w",stdout);
86
87 readint(n);
88 readint(m);
89 int x;
90 for (int a=1;a<=m;a++)
91 {
92 readint(x);
93 add_edge(x,a);
94 }
95 for (int a=1;a<=n;a++)
96 {
97 readint(need[a]);
98 }
99 readint(k);
100 for (int a=1;a<=k;a++)
101 {
102 readint(left[a]);
103 readint(right[a]);
104 readint(delta[a]);
105 }
106 for (int a=1;a<=n;a++)
107 l[a]=0,r[a]=k+1;
108 for (;;)
109 {
110 bool able=true;
111 for (int a=1;a<=n;a++)
112 if (l[a]+1!=r[a])
113 {
114 able=false;
115 break;
116 }
117 if (able) break;
118 for (int a=1;a<=n;a++)
119 z[a]=a,mid[a]=(l[a]+r[a])>>1;
120 sort(z+1,z+n+1,cmp);
121 memset(y,0,sizeof(y));
122 for (int a=1,b=1;a<=n;a++)
123 {
124 int now=z[a];
125 if (l[now]+1==r[now]) continue;
126 for (;b<=mid[now];b++)
127 {
128 if (left[b]>right[b])
129 {
130 modify(1,delta[b]);
131 modify(right[b]+1,-delta[b]);
132 modify(left[b],delta[b]);
133 }
134 else
135 {
136 modify(left[b],delta[b]);
137 modify(right[b]+1,-delta[b]);
138 }
139 }
140 long long value=0;
141 for (edge *e=v[now];e;e=e->next)
142 {
143 value+=query(e->e);
144 if (value>=need[now]) break;
145 }
146 if (value>=need[now]) r[now]=mid[now];
147 else l[now]=mid[now];
148 }
149 }
150 for (int a=1;a<=n;a++)
151 if (r[a]<=k) printf("%d
",r[a]);
152 else printf("NIE
");
153
154 return 0;
155 }
Sticks:
枚举最大的,检验剩下的两根最大的是否满足条件。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<algorithm>
5 #include<queue>
6
7 using namespace std;
8
9 const int maxk=60;
10 const int maxn=1000010;
11
12 int k,s[maxk],t[maxk],z[maxn];
13
14 struct rec
15 {
16 int col,p;
17 rec(){}
18 rec(int a,int b)
19 {
20 col=a;p=b;
21 }
22 bool operator<(const rec &a)const
23 {
24 return z[p]<z[a.p];
25 }
26 };
27
28 priority_queue<rec> heap;
29
30 int main()
31 {
32 freopen("sticks.in","r",stdin);
33 freopen("sticks.out","w",stdout);
34
35 scanf("%d",&k);
36 for (int a=1;a<=k;a++)
37 {
38 s[a]=t[a-1]+1;
39 int n;
40 scanf("%d",&n);
41 t[a]=s[a]+n-1;
42 for (int b=s[a];b<=t[a];b++)
43 scanf("%d",&z[b]);
44 sort(z+s[a],z+t[a]+1);
45 heap.push(rec(a,t[a]));
46 }
47 while (heap.size())
48 {
49 rec now=heap.top();
50 heap.pop();
51 int col=now.col;
52 int p=now.p;
53 int v=z[p];
54 if (heap.size()>=2)
55 {
56 now=heap.top();
57 int v1=z[heap.top().p];
58 heap.pop();
59 int v2=z[heap.top().p];
60 if (v1+v2>v)
61 {
62 printf("%d %d %d %d %d %d
",col,v,now.col,v1,heap.top().col,v2);
63 return 0;
64 }
65 heap.push(now);
66 }
67 if (p>s[col]) heap.push(rec(col,p-1));
68 }
69 printf("NIE
");
70
71 return 0;
72 }
Programming Contest:
基本的思路是费用流,写了个像修车的费用流-->TLE,然后改成每次找题目最少的进行增广-->TLE,然后将增广的bfs过程改成二分图匹配-->98,被卡常数,进行了一番常数优化才过。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<cctype>
5 #include<algorithm>
6 #include<queue>
7
8 using namespace std;
9
10 const int BUF_SIZE = 30;
11 char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1;
12
13 #define PTR_NEXT()
14 {
15 buf_s ++;
16 if (buf_s == buf_t)
17 {
18 buf_s = buf;
19 buf_t = buf + fread(buf, 1, BUF_SIZE, stdin);
20 }
21 }
22
23 #define readint(_n_)
24 {
25 while (*buf_s != '-' && !isdigit(*buf_s))
26 PTR_NEXT();
27 bool register _nega_ = false;
28 if (*buf_s == '-')
29 {
30 _nega_ = true;
31 PTR_NEXT();
32 }
33 int register _x_ = 0;
34 while (isdigit(*buf_s))
35 {
36 _x_ = _x_ * 10 + *buf_s - '0';
37 PTR_NEXT();
38 }
39 if (_nega_)
40 _x_ = -_x_;
41 (_n_) = (_x_);
42 }
43
44 const int maxn=510;
45 const int maxm=maxn*maxn;
46
47 int n,m,r,t,k,en,ans,result[maxn],x[maxn];
48
49 bool vis[maxn];
50
51 struct edge
52 {
53 int e,f;
54 edge *next;
55 }*v[maxn],ed[maxm];
56
57 void add_edge(int s,int e)
58 {
59 en++;
60 ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;
61 }
62
63 bool dfs(int now)
64 {
65 for (edge *e=v[now];e;e=e->next)
66 if (!vis[e->e])
67 {
68 vis[e->e]=true;
69 if (!result[e->e] || dfs(result[e->e]))
70 {
71 result[e->e]=now;
72 return true;
73 }
74 }
75 return false;
76 }
77
78 int main()
79 {
80 freopen("contest.in","r",stdin);
81 freopen("contest.out","w",stdout);
82
83 readint(n);
84 readint(m);
85 readint(r);
86 readint(t);
87 readint(k);
88 int s,e;
89 for (int a=1;a<=k;a++)
90 {
91 readint(s);
92 readint(e);
93 add_edge(s,e);
94 }
95 priority_queue< pair < int , int > > heap;
96 for (int a=1;a<=n;a++)
97 heap.push(make_pair(0,a));
98 t/=r;
99 int cnt=0;
100 while (heap.size())
101 {
102 int v=-heap.top().first;
103 int p=heap.top().second;
104 heap.pop();
105 memset(vis,false,sizeof(vis));
106 if (v<t && dfs(p))
107 {
108 cnt++;
109 ans+=(v+1)*r;
110 heap.push(make_pair(-v-1,p));
111 }
112 }
113 printf("%d %d
",cnt,ans);
114 for (int a=1;a<=m;a++)
115 if (result[a]) printf("%d %d %d
",result[a],a,r*x[result[a]]++);
116
117 return 0;
118 }