蒟蒻的bzoj小结
分类:
IT文章
•
2023-11-13 20:51:24
NOI2013,终于还是退役了。。。就把我在bzoj上刷过的水题贴上来吧,为了造(bao)福(fu)社会
大家千万不要学习我那个蛋疼的不用stl容器的习惯(除非你们省选和电子坑大一样是用cena和cena自带的编译器来评测的。。。)
bzoj1000
神题不会
bzoj1001
正解应该是平面图最小割转最短路,然后我会说网络流跑得飞快?
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxm 1000010
8 #define inf 0x3f3f3f3f
9
10 struct edge
11 {
12 int flow,to;
13 edge *next,*part;
14 }e[maxm<<3],*head[maxm];
15
16 int ne=0,s=1,t;
17 int q[maxm],d[maxm];
18
19 inline void add(int from,int to,int flow)
20 {
21 e[ne].to=to;
22 e[ne].flow=flow;
23 e[ne].next=head[from];
24 head[from]=&e[ne++];
25 }
26
27 inline void add_edge(int from,int to,int flow)
28 {
29 e[ne].part=&e[ne+1];
30 e[ne+1].part=&e[ne];
31 add(from,to,flow);
32 add(to,from,flow);
33 }
34
35 inline bool bfs()
36 {
37 memset(d,-1,sizeof(d));
38 int op=0,cls=1;
39 q[1]=s;
40 d[s]=1;
41 edge *p;
42 while (op != cls)
43 {
44 int x=q[++op];
45 for (p=head[x];p;p=p->next)
46 if (p->flow && d[p->to] == -1)
47 {
48 d[p->to]=d[x]+1;
49 q[++cls]=p->to;
50 }
51 }
52 return d[t] != -1;
53 }
54
55 int dfs(int now,int now_flow)
56 {
57 if (now == t)
58 return now_flow;
59 int out=now_flow;
60 edge *p;
61 for (p=head[now];p;p=p->next)
62 if (p->flow && d[p->to] == d[now]+1 && out)
63 {
64 int flow=dfs(p->to,min(p->flow,out));
65 p->flow-=flow;
66 p->part->flow+=flow;
67 out-=flow;
68 }
69 if (out == now_flow)
70 d[now]=-1;
71 return now_flow-out;
72 }
73
74 inline void dinic()
75 {
76 int ans=0;
77 while (bfs())
78 ans+=dfs(s,inf);
79 printf("%d
",ans);
80 }
81
82 inline void read(int &x)
83 {
84 char ch;
85 while (ch=getchar(),ch > '9' || ch < '0');
86 x=ch-'0';
87 while (ch=getchar(),ch <= '9' && ch >= '0')
88 x=(x<<3)+x+x+ch-'0';
89 }
90
91 inline bool init()
92 {
93 int n,m,x;
94 read(n);
95 read(m);
96 if (n == 1)
97 {
98 int ans=inf;
99 for (int i=1;i<m;i++)
100 {
101 read(x);
102 ans=min(ans,x);
103 }
104 printf("%d
",ans);
105 return 0;
106 }
107 else
108 {
109 if (m == 1)
110 {
111 int ans=inf;
112 for (int i=1;i<n;i++)
113 {
114 read(x);
115 ans=min(ans,x);
116 }
117 printf("%d",ans);
118 return 0;
119 }
120 else
121 {
122 t=n*m;
123 for (int i=1;i<=n;i++)
124 for (int j=1;j<m;j++)
125 {
126 read(x);
127 add_edge((i-1)*m+j,(i-1)*m+j+1,x);
128 }
129 for (int i=1;i<n;i++)
130 for (int j=1;j<=m;j++)
131 {
132 read(x);
133 add_edge((i-1)*m+j,i*m+j,x);
134 }
135 for (int i=1;i<n;i++)
136 for (int j=1;j<m;j++)
137 {
138 read(x);
139 add_edge((i-1)*m+j,i*m+j+1,x);
140 }
141 return 1;
142 }
143 }
144 }
145
146 int main()
147 {
148 if (init())
149 dinic();
150 return 0;
151 }
View Code
bzoj1002
裸高精
1 #include <cmath>
2 #include <string>
3 #include <cstdio>
4 #include <cstdlib>
5 #include <cstring>
6 #include <iostream>
7 #include <algorithm>
8 using namespace std;
9
10 #ifdef unix
11 #define ll "%lld"
12 #else
13 #define ll "%I64d"
14 #endif
15 class wkint {
16 private:
17 long long a[1510];
18 int len;
19 public:
20 wkint();
21 wkint(int t);
22 void read();
23 void print();
24 wkint operator + (const wkint &t) const;
25 wkint operator - (const wkint &t) const;
26 wkint operator * (const wkint &t) const;
27 wkint operator * (const int &t) const;
28 wkint operator ^ (const int &t) const;
29 wkint operator / (const int &t) const;
30 int operator % (const int &t) const;
31 bool operator < (const wkint &t) const;
32 bool operator > (const wkint &t) const;
33 bool operator == (const wkint &t) const;
34 bool operator != (const wkint &t) const;
35 };
36
37 wkint::wkint() {
38 len = 1;
39 memset(a, 0, sizeof(a));
40 }
41 wkint::wkint(int t) {
42 len = 1;
43 a[1] = t;
44 }
45 void wkint::read() {
46 string tmp;
47 cin >> tmp;
48 int lenT = tmp.length();
49 len = (lenT + 7) / 8;
50 int ptr = len, now = 0;
51 for (int i = 0; i < lenT; i ++) {
52 now *= 10; now += (int)(tmp[i] - '0');
53 if (!((lenT - i - 1) % 8)) {
54 a[ptr] = now;
55 now = 0;
56 ptr --;
57 }
58 }
59 }
60 void wkint::print() {
61 printf(ll, a[len]);
62 for (int i = len - 1; i >= 1; i --) {
63 int ws = (int)log10((long double)(a[i] + 1)) + 1;
64 for (int j = 1; j <= 8 - ws; j ++) printf("0");
65 printf(ll, a[i]);
66 }
67 printf("
");
68 }
69 wkint wkint::operator + (const wkint &t) const {
70 wkint res;
71 int maxlen = max(t.len, len);
72 for (int i = 1; i <= maxlen; i ++) {
73 res.a[i] += a[i] + t.a[i];
74 if (res.a[i] >= 100000000) {
75 res.a[i + 1] += res.a[i] / 100000000;
76 res.a[i] %= 100000000;
77 }
78 }
79 if (res.a[maxlen + 1]) maxlen ++;
80 res.len = maxlen;
81 return res;
82 }
83 wkint wkint::operator - (const wkint &t) const {
84 wkint res;
85 int maxlen = max(t.len, len);
86 for (int i = 1; i <= maxlen; i ++) {
87 res.a[i] += a[i] - t.a[i];
88 if (res.a[i] < 0) {
89 res.a[i + 1] -= 1;
90 res.a[i] += 100000000;
91 }
92 }
93 while (!res.a[maxlen]) maxlen --;
94 res.len = maxlen;
95 return res;
96 }
97 wkint wkint::operator * (const wkint &t) const {
98 wkint res;
99 int maxlen = t.len + len - 1;
100 for (int i = 1; i <= len; i ++)
101 for (int j = 1; j <= t.len; j ++) {
102 res.a[i + j - 1] += a[i] * t.a[j];
103 }
104 for (int i = 1; i <= maxlen; i ++)
105 if (res.a[i] > 100000000) {
106 res.a[i + 1] += res.a[i] / 100000000;
107 res.a[i] %= 100000000;
108 }
109 if (res.a[maxlen + 1]) maxlen ++;
110 res.len = maxlen;
111 return res;
112 }
113 wkint wkint::operator * (const int &t) const {
114 wkint res;
115 res.len = len;
116 for (int i = 1; i <= len; i ++) {
117 res.a[i] += a[i] * t;
118 if (res.a[i] > 100000000) {
119 res.a[i + 1] += res.a[i] / 100000000;
120 res.a[i] %= 100000000;
121 }
122 }
123 if (res.a[res.len + 1]) res.len ++;
124 return res;
125 }
126 wkint wkint::operator ^ (const int &t) const {
127 wkint res = wkint(1), tmp;
128 int now = t;
129 memcpy(tmp.a, a, sizeof(a));
130 tmp.len = len;
131 while (now) {
132 if (now & 1) res = res * tmp;
133 tmp = tmp * tmp;
134 now >>= 1;
135 }
136 return res;
137 }
138 wkint wkint::operator / (const int &t) const {
139 wkint res;
140 long long now = 0;
141 res.len = len;
142 for (int i = len; i >= 1; i --) {
143 now *= 100000000, now += a[i];
144 if (now < t) {
145 res.a[i] = 0;
146 } else {
147 res.a[i] = now / t;
148 now %= t;
149 }
150 }
151 while (!res.a[res.len]) res.len --;
152 return res;
153 }
154 int wkint::operator % (const int &t) const {
155 long long now = 0;
156 for (int i = len; i >= 1; i --) {
157 now *= 100000000, now += a[i];
158 now %= t;
159 }
160 return (int)now;
161 }
162 bool wkint::operator < (const wkint &t) const {
163 if (len < t.len) return true;
164 if (len > t.len) return false;
165 for (int i = len; i >= 1; i --)
166 if (a[i] < t.a[i]) {
167 return true;
168 } else if (a[i] > t.a[i]) {
169 return false;
170 }
171 return false;
172 }
173 bool wkint::operator > (const wkint &t) const {
174 if (len > t.len) return true;
175 if (len < t.len) return false;
176 for (int i = len; i >= 1; i --)
177 if (a[i] > t.a[i]) {
178 return true;
179 } else if (a[i] < t.a[i]) {
180 return false;
181 }
182 return false;
183 }
184 bool wkint::operator == (const wkint &t) const {
185 if (t.len != len) return false;
186 for (int i = 1; i <= len; i ++)
187 if (a[i] != t.a[i]) {
188 return false;
189 }
190 return true;
191 }
192 bool wkint::operator != (const wkint &t) const {
193 if (t.len != len) return true;
194 for (int i = 1; i <= len; i ++)
195 if (a[i] != t.a[i]) {
196 return true;
197 }
198 return false;
199 }
200
201 wkint ans[101];
202
203 int main()
204 {
205 int n;
206 scanf("%d",&n);
207 ans[1]=1;
208 ans[2]=5;
209 for (int i=3;i<=n;i++)
210 ans[i]=ans[i-1]+ans[i-1]+ans[i-1]-ans[i-2]+2;
211 ans[n].print();
212 return 0;
213 }
View Code
bzoj1003
预处理两天之间的最短路,然后DP
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 30
5 #define maxt 110
6 #define maxm 610
7 #define inf 0x3f3f3f3f
8
9 struct edge
10 {
11 int to,dist;
12 edge *next;
13 }e[maxm],*head[maxn];
14
15 int n;
16 int ne=0;
17 int q[maxn],d[maxn];
18 bool flag[maxn],vis[maxn];
19
20 inline int min(int a,int b)
21 {
22 return a < b ? a : b;
23 }
24
25 inline int spfa()
26 {
27 memset(d,0x3f,sizeof(d));
28 memset(vis,0,sizeof(vis));
29 int op=0,cls=1;
30 q[1]=1;
31 d[1]=0;
32 vis[1]=1;
33 while (op != cls)
34 {
35 op=op == maxn-1 ? 0 : op+1;
36 int x=q[op];
37 for (edge *p=head[x];p;p=p->next)
38 if (flag[p->to] && d[p->to] > d[x]+p->dist)
39 {
40 d[p->to]=d[x]+p->dist;
41 if (!vis[p->to])
42 {
43 if (op != cls)
44 {
45 int now=op == maxn-1 ? 0 : op+1;
46 if (d[p->to] < d[now])
47 {
48 q[op]=p->to;
49 op=op ? op-1 : maxn-1;
50 }
51 else
52 {
53 cls=cls == maxn-1 ? 0 : cls+1;
54 q[cls]=p->to;
55 }
56 }
57 else
58 {
59 cls=cls == maxn-1 ? 0 : cls+1;
60 q[cls]=p->to;
61 }
62 }
63 }
64 vis[x]=0;
65 }
66 return d[n];
67 }
68
69 inline void add_edge(int from,int to,int dist)
70 {
71 e[ne].to=to;
72 e[ne].dist=dist;
73 e[ne].next=head[from];
74 head[from]=&e[ne++];
75 }
76
77 int f[maxt];
78 int cost[maxt][maxt];
79 bool acc[maxn][maxt];
80
81 int main()
82 {
83 int t,m,k;
84 scanf("%d%d%d%d",&t,&n,&k,&m);
85 for (int i=1;i<=m;i++)
86 {
87 int x,y,z;
88 scanf("%d%d%d",&x,&y,&z);
89 add_edge(x,y,z);
90 add_edge(y,x,z);
91 }
92 int _;
93 scanf("%d",&_);
94 memset(acc,1,sizeof(acc));
95 while (_--)
96 {
97 int x,y,z;
98 scanf("%d%d%d",&x,&y,&z);
99 for (int i=y;i<=z;i++)
100 acc[x][i]=0;
101 }
102 for (int i=1;i<=t;i++)
103 {
104 memset(flag,1,sizeof(flag));
105 for (int j=i;j<=t;j++)
106 {
107 for (int k=2;k<n;k++)
108 if (!acc[k][j])
109 flag[k]=0;
110 cost[i][j]=spfa();
111 }
112 }
113 for (int i=1;i<=t;i++)
114 if (cost[1][i] == inf)
115 f[i]=inf;
116 else
117 f[i]=cost[1][i]*i;
118 for (int i=2;i<=t;i++)
119 for (int j=1;j<i;j++)
120 if (cost[j+1][i] != inf)
121 f[i]=min(f[i],f[j]+cost[j+1][i]*(i-j)+k);
122 printf("%d
",f[t]);
123 return 0;
124 }
View Code
bzoj1005
prufer编码+高精
1 #include <cmath>
2 #include <string>
3 #include <cstdio>
4 #include <cstdlib>
5 #include <cstring>
6 #include <iostream>
7 #include <algorithm>
8 using namespace std;
9
10 #define maxn 1010
11
12 #ifdef unix
13 #define ll "%lld"
14 #else
15 #define ll "%I64d"
16 #endif
17 class wkint {
18 private:
19 long long a[1510];
20 int len;
21 public:
22 wkint();
23 wkint(int t);
24 void read();
25 void print();
26 wkint operator + (const wkint &t) const;
27 wkint operator - (const wkint &t) const;
28 wkint operator * (const wkint &t) const;
29 wkint operator * (const int &t) const;
30 wkint operator ^ (const int &t) const;
31 wkint operator / (const int &t) const;
32 int operator % (const int &t) const;
33 bool operator < (const wkint &t) const;
34 bool operator > (const wkint &t) const;
35 bool operator == (const wkint &t) const;
36 bool operator != (const wkint &t) const;
37 };
38
39 wkint::wkint() {
40 len = 1;
41 memset(a, 0, sizeof(a));
42 }
43 wkint::wkint(int t) {
44 len = 1;
45 a[1] = t;
46 }
47 void wkint::read() {
48 string tmp;
49 cin >> tmp;
50 int lenT = tmp.length();
51 len = (lenT + 7) / 8;
52 int ptr = len, now = 0;
53 for (int i = 0; i < lenT; i ++) {
54 now *= 10; now += (int)(tmp[i] - '0');
55 if (!((lenT - i - 1) % 8)) {
56 a[ptr] = now;
57 now = 0;
58 ptr --;
59 }
60 }
61 }
62 void wkint::print() {
63 printf(ll, a[len]);
64 for (int i = len - 1; i >= 1; i --) {
65 int ws = (int)log10((long double)(a[i] + 1)) + 1;
66 for (int j = 1; j <= 8 - ws; j ++) printf("0");
67 printf(ll, a[i]);
68 }
69 printf("
");
70 }
71 wkint wkint::operator + (const wkint &t) const {
72 wkint res;
73 int maxlen = max(t.len, len);
74 for (int i = 1; i <= maxlen; i ++) {
75 res.a[i] += a[i] + t.a[i];
76 if (res.a[i] >= 100000000) {
77 res.a[i + 1] += res.a[i] / 100000000;
78 res.a[i] %= 100000000;
79 }
80 }
81 if (res.a[maxlen + 1]) maxlen ++;
82 res.len = maxlen;
83 return res;
84 }
85 wkint wkint::operator - (const wkint &t) const {
86 wkint res;
87 int maxlen = max(t.len, len);
88 for (int i = 1; i <= maxlen; i ++) {
89 res.a[i] += a[i] - t.a[i];
90 if (res.a[i] < 0) {
91 res.a[i + 1] -= 1;
92 res.a[i] += 100000000;
93 }
94 }
95 while (!res.a[maxlen]) maxlen --;
96 res.len = maxlen;
97 return res;
98 }
99 wkint wkint::operator * (const wkint &t) const {
100 wkint res;
101 int maxlen = t.len + len - 1;
102 for (int i = 1; i <= len; i ++)
103 for (int j = 1; j <= t.len; j ++) {
104 res.a[i + j - 1] += a[i] * t.a[j];
105 }
106 for (int i = 1; i <= maxlen; i ++)
107 if (res.a[i] > 100000000) {
108 res.a[i + 1] += res.a[i] / 100000000;
109 res.a[i] %= 100000000;
110 }
111 if (res.a[maxlen + 1]) maxlen ++;
112 res.len = maxlen;
113 return res;
114 }
115 wkint wkint::operator * (const int &t) const {
116 wkint res;
117 res.len = len;
118 for (int i = 1; i <= len; i ++) {
119 res.a[i] += a[i] * t;
120 if (res.a[i] > 100000000) {
121 res.a[i + 1] += res.a[i] / 100000000;
122 res.a[i] %= 100000000;
123 }
124 }
125 if (res.a[res.len + 1]) res.len ++;
126 return res;
127 }
128 wkint wkint::operator ^ (const int &t) const {
129 wkint res = wkint(1), tmp;
130 int now = t;
131 memcpy(tmp.a, a, sizeof(a));
132 tmp.len = len;
133 while (now) {
134 if (now & 1) res = res * tmp;
135 tmp = tmp * tmp;
136 now >>= 1;
137 }
138 return res;
139 }
140 wkint wkint::operator / (const int &t) const {
141 wkint res;
142 long long now = 0;
143 res.len = len;
144 for (int i = len; i >= 1; i --) {
145 now *= 100000000, now += a[i];
146 if (now < t) {
147 res.a[i] = 0;
148 } else {
149 res.a[i] = now / t;
150 now %= t;
151 }
152 }
153 while (!res.a[res.len]) res.len --;
154 return res;
155 }
156 int wkint::operator % (const int &t) const {
157 long long now = 0;
158 for (int i = len; i >= 1; i --) {
159 now *= 100000000, now += a[i];
160 now %= t;
161 }
162 return (int)now;
163 }
164 bool wkint::operator < (const wkint &t) const {
165 if (len < t.len) return true;
166 if (len > t.len) return false;
167 for (int i = len; i >= 1; i --)
168 if (a[i] < t.a[i]) {
169 return true;
170 } else if (a[i] > t.a[i]) {
171 return false;
172 }
173 return false;
174 }
175 bool wkint::operator > (const wkint &t) const {
176 if (len > t.len) return true;
177 if (len < t.len) return false;
178 for (int i = len; i >= 1; i --)
179 if (a[i] > t.a[i]) {
180 return true;
181 } else if (a[i] < t.a[i]) {
182 return false;
183 }
184 return false;
185 }
186 bool wkint::operator == (const wkint &t) const {
187 if (t.len != len) return false;
188 for (int i = 1; i <= len; i ++)
189 if (a[i] != t.a[i]) {
190 return false;
191 }
192 return true;
193 }
194 bool wkint::operator != (const wkint &t) const {
195 if (t.len != len) return true;
196 for (int i = 1; i <= len; i ++)
197 if (a[i] != t.a[i]) {
198 return true;
199 }
200 return false;
201 }
202
203 int d[maxn];
204
205 int main()
206 {
207 int n;
208 scanf("%d",&n);
209 int cnt=0,sum=0;
210 for (int i=1;i<=n;i++)
211 {
212 scanf("%d",&d[i]);
213 if (d[i] == -1)
214 cnt++;
215 else
216 {
217 d[i]--;
218 sum+=d[i];
219 }
220 }
221 wkint ans=1;
222 for (int i=1;i<=n-2-sum;i++)
223 ans=ans*cnt;
224 for (int i=n-1-sum;i<=n-2;i++)
225 ans=ans*i;
226 for (int i=1;i<=n;i++)
227 if (d[i] != -1)
228 for (int j=1;j<=d[i];j++)
229 ans=ans/j;
230 ans.print();
231 return 0;
232 }
View Code
bzoj1006
弦图的完美消除序列,可以参考cdq的论文
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 10010
5 #define maxm 1000010
6
7 struct edge
8 {
9 int to;
10 edge *next;
11 }e[maxm<<1],*head[maxn];
12
13 int ne=0;
14
15 inline void add_edge(int from,int to)
16 {
17 e[ne].to=to;
18 e[ne].next=head[from];
19 head[from]=&e[ne++];
20 }
21
22 inline void read(int &x)
23 {
24 char ch;
25 while (ch=getchar(),ch > '9' || ch < '0');
26 x=ch-'0';
27 while (ch=getchar(),ch <= '9' && ch >= '0')
28 x=(x<<3)+x+x+ch-'0';
29 }
30
31 int d[maxn],col[maxn],a[maxn];
32 int sta[maxn];
33 bool flag[maxn];
34
35 int main()
36 {
37 int n,m;
38 read(n);
39 read(m);
40 for (int i=1;i<=m;i++)
41 {
42 int x,y;
43 read(x);
44 read(y);
45 add_edge(x,y);
46 add_edge(y,x);
47 }
48 d[0]=-1;
49 for (int i=n;i;i--)
50 {
51 int now=0;
52 for (int j=1;j<=n;j++)
53 if (!flag[j] && d[j] > d[now])
54 now=j;
55 flag[now]=1;
56 a[i]=now;
57 for (edge *p=head[now];p;p=p->next)
58 d[p->to]++;
59 }
60 int ans=0;
61 int top=1;
62 memset(flag,0,sizeof(flag));
63 for (int i=n;i;i--)
64 {
65 int x=a[i];
66 for (edge *p=head[x];p;p=p->next)
67 {
68 sta[++top]=col[p->to];
69 flag[col[p->to]]=1;
70 }
71 int now;
72 for (now=1;flag[now];now++);
73 col[x]=now;
74 if (now > ans)
75 ans=now;
76 while (top)
77 flag[sta[top--]]=0;
78 }
79 printf("%d
",ans);
80 return 0;
81 }
View Code
bzoj1007
半平面交,按斜率排序之后开个栈扫一遍
1 #include <cstdio>
2 #include <cmath>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 50010
8 #define eps 1e-6
9
10 struct line
11 {
12 int k,b,num;
13
14 inline bool operator < (const line x) const
15 {
16 return (k < x.k) || (k == x.k && b > x.b);
17 }
18 }a[maxn];
19
20 inline void read(int &x)
21 {
22 char ch;
23 bool flag=0;
24 while (ch=getchar(),(ch > '9' || ch < '0') && (ch != '-'));
25 if (ch == '-')
26 flag=1;
27 else
28 x=ch-'0';
29 while (ch=getchar(),ch <= '9' && ch >= '0')
30 x=(x<<3)+x+x+ch-'0';
31 if (flag)
32 x=-x;
33 }
34
35 inline double point(int x,int y)
36 {
37 return (double)(a[y].b-a[x].b)/(a[x].k-a[y].k);
38 }
39
40 int sta[maxn];
41 int ans[maxn];
42
43 int main()
44 {
45 int n;
46 read(n);
47 if (n == 1)
48 {
49 puts("1");
50 return 0;
51 }
52 for (int i=1;i<=n;i++)
53 {
54 read(a[i].k);
55 read(a[i].b);
56 a[i].num=i;
57 }
58 sort(a+1,a+n+1);
59 int top=1;
60 sta[top]=1;
61 for (int i=2;i<=n;i++)
62 {
63 if (a[i].k != a[i-1].k)
64 break;
65 if (i == n)
66 {
67 printf("%d ",a[1].num);
68 return 0;
69 }
70 }
71 for (int i=2;i<=n;i++)
72 {
73 if (a[i].k == a[sta[top]].k)
74 continue;
75 if (top < 2)
76 sta[++top]=i;
77 else
78 {
79 while (top >= 2 && point(sta[top],i) <= point(sta[top-1],sta[top]))
80 top--;
81 sta[++top]=i;
82 }
83 }
84 for (int i=1;i<=top;i++)
85 ans[i]=a[sta[i]].num;
86 sort(ans+1,ans+top+1);
87 for (int i=1;i<=top;i++)
88 printf("%d ",ans[i]);
89 return 0;
90 }
View Code
bzoj1008
写出DP方程(我这个蒟蒻才会干这种事。。。)然后找规律快速幂
1 #include <cstdio>
2
3 #define mod 100003LL
4
5 #ifdef unix
6 #define LL "%lld"
7 #else
8 #define LL "%I64d"
9 #endif
10
11 long long n,m;
12
13 inline long long calc(long long a,long long b)
14 {
15 long long ans=1,wk=a;
16 while (b)
17 {
18 if (b & 1)
19 (ans*=wk)%=mod;
20 (wk*=wk)%=mod;
21 b>>=1;
22 }
23 return ans;
24 }
25
26 int main()
27 {
28 scanf(LL LL,&m,&n);
29 long long ans=calc(m,n)-(calc(m-1,n-1)*m)%mod;
30 if (ans < 0)
31 ans+=mod;
32 printf(LL,ans);
33 return 0;
34 }
View Code
bzoj1009
KMP之后DP,需要矩阵快速幂优化,由于我太弱了不会KMP就只有写AC自动机了
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 30
5
6 struct Node
7 {
8 Node *s[10];
9 Node *fail;
10 }t[maxn],*root,*q[maxn];
11
12 int ne=1;
13 char s[maxn];
14
15 inline void insert(char* str)
16 {
17 int l=strlen(str);
18 Node* now=root;
19 for (int i=0;i<l;i++)
20 {
21 char p=str[i]-'0';
22 if (now->s[p] == NULL)
23 now->s[p]=&t[++ne];
24 now=now->s[p];
25 }
26 }
27
28 inline void build()
29 {
30 for (int i=0;i<10;i++)
31 if (root->s[i] == NULL)
32 root->s[i]=root;
33 int op=0,cls=1;
34 q[1]=root;
35 while (op != cls)
36 {
37 Node* now=q[++op];
38 for (int i=0;i<10;i++)
39 if (now->s[i] != NULL)
40 {
41 if (now->s[i] != root)
42 q[++cls]=now->s[i];
43 if (now != root)
44 now->s[i]->fail=now->fail->s[i];
45 else
46 now->s[i]->fail=root;
47 }
48 else
49 now->s[i]=now->fail->s[i];
50 }
51 }
52
53 int ans[maxn][maxn],temp[maxn][maxn],wk[maxn][maxn],sum[maxn][maxn];
54
55 int main()
56 {
57 root=&t[1];
58 int n,m,mod;
59 scanf("%d%d%d",&n,&m,&mod);
60 scanf("%s",s);
61 insert(s);
62 build();
63 ans[1][1]=1;
64 for (int i=1;i<=m;i++)
65 for (int j=0;j<10;j++)
66 {
67 int x=t[i].s[j]-t;
68 if (x < ne)
69 wk[i][x]++;
70 }
71 for (int i=1;i<=m;i++)
72 sum[i][i]=1;
73 while (n)
74 {
75 if (n&1)
76 {
77 memset(temp,0,sizeof(temp));
78 for (int i=1;i<=m;i++)
79 for (int j=1;j<=m;j++)
80 for (int k=1;k<=m;k++)
81 (temp[i][j]+=sum[i][k]*wk[k][j])%=mod;
82 for (int i=1;i<=m;i++)
83 for (int j=1;j<=m;j++)
84 sum[i][j]=temp[i][j];
85 }
86 memset(temp,0,sizeof(temp));
87 n>>=1;
88 for (int i=1;i<=m;i++)
89 for (int j=1;j<=m;j++)
90 for (int k=1;k<=m;k++)
91 (temp[i][j]+=wk[i][k]*wk[k][j])%=mod;
92 for (int i=1;i<=m;i++)
93 for (int j=1;j<=m;j++)
94 wk[i][j]=temp[i][j];
95 }
96 memset(temp,0,sizeof(temp));
97 for (int i=1;i<=m;i++)
98 for (int j=1;j<=m;j++)
99 for (int k=1;k<=m;k++)
100 (temp[i][j]+=ans[i][k]*sum[k][j])%=mod;
101 int now=0;
102 for (int i=1;i<=m;i++)
103 (now+=temp[1][i])%=mod;
104 printf("%d
",now);
105 return 0;
106 }
View Code
bzoj1010
斜率优化的DP
1 #include <cstdio>
2
3 #define maxn 50010
4
5 #ifdef unix
6 #define LL "%lld"
7 #else
8 #define LL "%I64d"
9 #endif
10
11 long long n,l;
12 long long sum[maxn],q[maxn],dp[maxn];
13
14 inline long long sqr(long long x)
15 {
16 return x * x;
17 }
18
19 inline long long A(long long x)
20 {
21 return sum[x]+x;
22 }
23
24 inline long long B(long long x)
25 {
26 return sum[x]+x+l+1;
27 }
28
29 int main()
30 {
31 scanf(LL LL,&n,&l);
32 for (long long i=1;i<=n;i++)
33 {
34 long long x;
35 scanf(LL ,&x);
36 sum[i]=sum[i-1]+x;
37 }
38 long long op=0,cls=0;
39 for (long long i=1;i<=n;i++)
40 {
41 while (op < cls && dp[q[op+1]]-dp[q[op]]+sqr(B(q[op+1]))-sqr(B(q[op])) <= 2*A(i) * (B(q[op+1])-B(q[op])))
42 op++;
43 dp[i]=dp[q[op]]+sqr(A(i)-B(q[op]));
44 while (op < cls)
45 {
46 if ((dp[q[cls]]-dp[q[cls-1]]+sqr(B(q[cls]))-sqr(B(q[cls-1]))) * (B(i)-B(q[cls])) > (dp[i]-dp[q[cls]]+sqr(B(i))-sqr(B(q[cls]))) * (B(q[cls])-B(q[cls-1])))
47 cls--;
48 else
49 break;
50 }
51 q[++cls]=i;
52 }
53 printf(LL,dp[n]);
54 return 0;
55 }
View Code
bzoj1011
一直想不出来怎么优化,结果做法是。。。太过于遥远的行星可以理解为距离相同
1 #include <cstdio>
2 #include <cmath>
3
4 #define maxn 100010
5 #define t 60
6 #define eps 1e-8
7
8 double f[maxn],a;
9 int n,m[maxn];
10
11 int main()
12 {
13 scanf("%d%lf",&n,&a);
14 for (int i=1;i<=n;i++)
15 scanf("%d",&m[i]);
16 for (int i=1;i<=t;i++)
17 {
18 int x=(int)(eps+floor(a*i));
19 for (int j=1;j<=x;j++)
20 f[i]+=1.0*m[i]*m[j]/(i-j);
21 }
22 for (int i=t+1;i<=n;i++)
23 {
24 int l=(int)(eps+floor(a*(i-t)));
25 int x=(int)(eps+floor(a*i));
26 for (int j=l+1;j<=x;j++)
27 f[i]+=1.0*m[i]*m[j]/(i-j);
28 f[i]+=1.0*m[i]*f[i-t]/m[i-t]*(i-t-1.0*l/2)/(i-1.0*l/2);
29 }
30 for (int i=1;i<=n;i++)
31 printf("%.6lf
",f[i]);
32 return 0;
33 }
View Code
bzoj1012
可以用线段树,单调队列等一堆东西来写。。。
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 100010
7
8 int q[maxn],num[maxn];
9 int cls=0;
10 int n,d;
11
12 int main()
13 {
14 char s[2];
15 scanf("%d%d",&n,&d);
16 int ans=0,x,sum=0;
17 while (n--)
18 {
19 scanf("%s%d",s,&x);
20 if (s[0] == 'A')
21 {
22 (x+=ans)%=d;
23 q[++cls]=x;
24 num[cls]=++sum;
25 while (q[cls] > q[cls-1] && cls > 1)
26 {
27 q[cls-1]=q[cls];
28 num[cls-1]=num[cls];
29 cls--;
30 }
31 }
32 else
33 {
34 int now=lower_bound(num+1,num+cls+1,sum-x+1)-num;
35 printf("%d
",q[now]);
36 ans=q[now];
37 }
38 }
39 return 0;
40 }
View Code
bzoj1013
高斯消元模板题
1 #include <cstdio>
2 #include <cmath>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 15
8 #define eps 1e-6
9
10 int n;
11 double now[maxn],f[maxn][maxn],ans[maxn];
12
13 inline void gauss()
14 {
15 for (int i=1;i<n;i++)
16 {
17 int _max=i;
18 for (int j=i+1;j<=n;j++)
19 if (fabs(f[j][i]) > fabs(f[_max][i]))
20 _max=i;
21 if (fabs(f[_max][i]) > eps)
22 {
23 for (int j=1;j<=n+1;j++)
24 swap(f[_max][j],f[i][j]);
25 for (int j=i+1;j<=n;j++)
26 if (fabs(f[j][i]) > eps)
27 {
28 double now=-f[j][i]/f[i][i];
29 for (int k=i;k<=n+1;k++)
30 f[j][k]+=f[i][k]*now;
31 }
32 }
33 }
34 for (int i=n;i;i--)
35 {
36 double now=f[i][n+1];
37 for (int j=i+1;j<=n;j++)
38 now-=ans[j]*f[i][j];
39 ans[i]=now/f[i][i];
40 }
41 for (int i=1;i<n;i++)
42 printf("%.3lf ",ans[i]);
43 printf("%.3lf
",ans[n]);
44 }
45
46 int main()
47 {
48 scanf("%d",&n);
49 for (int i=1;i<=n;i++)
50 scanf("%lf",&now[i]);
51 for (int i=1;i<=n;i++)
52 for (int j=1;j<=n;j++)
53 {
54 double x;
55 scanf("%lf",&x);
56 f[i][j]=2*(now[j]-x);
57 f[i][n+1]+=now[j]*now[j]-x*x;
58 }
59 gauss();
60 return 0;
61 }
View Code
bzoj1014
splay维护hash值
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 300010
5
6 const unsigned int mod=27;
7
8 unsigned int hash[maxn];
9
10 struct Node
11 {
12 int c,size;
13 unsigned int v;
14 Node *s[2],*par;
15 Node()
16 {
17 c=size=0;
18 v=0;
19 }
20 };
21
22 struct splay
23 {
24 Node t[maxn],null;
25 Node *root;
26 int ne;
27
28 splay()
29 {
30 null.s[0]=null.s[1]=null.par=&null;
31 t[0].s[0]=&null,t[0].s[1]=&t[1],t[0].par=&null,t[0].size=2,t[0].c=0,t[0].v=0;
32 t[1].s[0]=&null,t[1].s[1]=&null,t[1].par=&t[0],t[1].size=1,t[1].c=0,t[1].v=0;
33 root=&t[0];
34 ne=2;
35 }
36
37 void travel(Node* now)
38 {
39 if (now->s[0] != &null)
40 travel(now->s[0]);
41 printf("%c",now->c+'a'-1);
42 if (now->s[1] != &null)
43 travel(now->s[1]);
44 }
45
46 inline void _update(Node* now)
47 {
48 now->size=now->s[0]->size+now->s[1]->size+1;
49 now->v=now->s[0]->v+now->c*hash[now->s[0]->size]+now->s[1]->v*hash[now->s[0]->size+1];
50 }
51
52 inline void _rot(Node* now,int l)
53 {
54 int r=!l;
55 Node* s=now->s[l];
56 Node* p=now->par;
57 (now->s[l]=s->s[r])->par=now;
58 (s->s[r]=now)->par=s;
59 s->par=p;
60 if (p != &null)
61 p->s[now == p->s[1]]=s;
62 _update(now);
63 _update(s);
64 }
65
66 inline void _splay(Node* now,Node* goal)
67 {
68 while (now->par != goal)
69 {
70 Node* p=now->par;
71 Node* g=p->par;
72 bool dp=now == p->s[1];
73 bool dg=p == g->s[1];
74 if (g == goal)
75 {
76 _rot(p,dp);
77 break;
78 }
79 if (dp == dg)
80 {
81 _rot(g,dg);
82 _rot(p,dp);
83 }
84 else
85 {
86 _rot(p,dp);
87 _rot(g,dg);
88 }
89 }
90 if (goal == &null)
91 root=now;
92 }
93
94 inline Node* _select(int v)
95 {
96 Node* now=root;
97 while (1)
98 {
99 if (now == &null)
100 return now;
101 if (now->s[0]->size+1 == v)
102 return now;
103 if (v <= now->s[0]->size)
104 now=now->s[0];
105 else
106 {
107 v-=now->s[0]->size+1;
108 now=now->s[1];
109 }
110 }
111 }
112
113 inline void change(int pos,char ch)
114 {
115 Node* p=_select(pos);
116 _splay(p,&null);
117 p->c=ch-'a'+1;
118 _update(p);
119 }
120
121 inline void insert(int pos,char ch)
122 {
123 Node* p=_select(pos);
124 Node* q=_select(pos+1);
125 _splay(p,&null);
126 _splay(q,root);
127 (q->s[0]=&t[ne++])->par=q;
128 Node* now=q->s[0];
129 now->s[0]=now->s[1]=&null;
130 now->c=ch-'a'+1;
131 now->size=1;
132 now->v=ch-'a'+1;
133 _update(q);
134 _update(p);
135 }
136
137 inline bool check(int x,int y,int len)
138 {
139 Node* p=_select(x);
140 Node* q=_select(x+len+1);
141 _splay(p,&null);
142 _splay(q,root);
143 unsigned int ans=q->s[0]->v;
144 p=_select(y);
145 q=_select(y+len+1);
146 _splay(p,&null);
147 _splay(q,root);
148 return q->s[0]->v == ans;
149 }
150
151 inline int query(int x,int y)
152 {
153 int len=root->size;
154 if (x == y)
155 return len-x-1;
156 Node* p=_select(x+1);
157 Node* q=_select(y+1);
158 if (p->c != q->c)
159 return 0;
160 int l=1,r=len-y,ans=0;
161 while (l < r)
162 {
163 int mid=(l+r)>>1;
164 if (check(x,y,mid))
165 {
166 ans=mid;
167 l=mid+1;
168 }
169 else
170 r=mid;
171 }
172 return ans;
173 }
174 }t;
175
176 int main()
177 {
178 //freopen("1.in","r",stdin);
179 //freopen("1.out","w",stdout);
180 int _,x,y;
181 char ch[2],s[2];
182 char st[maxn];
183 scanf("%s",st);
184 hash[0]=1;
185 for (int i=1;i<=maxn;i++)
186 hash[i]=hash[i-1] * mod;
187 int len=strlen(st);
188 for (int i=0;i<len;i++)
189 t.insert(i+1,st[i]);
190 scanf("%d",&_);
191 while (_--)
192 {
193 scanf("%s",ch);
194 if (ch[0] == 'Q')
195 {
196 scanf("%d%d",&x,&y);
197 if (x > y)
198 x^=y^=x^=y;
199 printf("%d
",t.query(x,y));
200 }
201 if (ch[0] == 'R')
202 {
203 scanf("%d%s",&x,s);
204 t.change(x+1,s[0]);
205 }
206 if (ch[0] == 'I')
207 {
208 scanf("%d%s",&x,s);
209 t.insert(x+1,s[0]);
210 }
211 }
212 return 0;
213 }
View Code
bzoj1015
倒着做并查集
1 #include <cstdio>
2 #include <bitset>
3
4 using namespace std;
5
6 #define maxn 2000010
7 #define maxm 200010
8
9 bitset <maxn> flag;
10
11 struct edge
12 {
13 int to;
14 edge *next;
15 }e[maxm<<1],*head[maxn];
16
17 int n,m,ne=0;
18 int f[maxn],r[maxn];
19 int des[maxn],ans[maxn];
20
21 int find(int x)
22 {
23 if (f[x] == x)
24 return x;
25 return f[x]=find(f[x]);
26 }
27
28 int _union(int a,int b)
29 {
30 int x=find(a);
31 int y=find(b);
32 if (x == y)
33 return 0;
34 if (r[x] < r[y])
35 {
36 f[x]=y;
37 r[y]+=r[x];
38 }
39 else
40 {
41 f[y]=x;
42 r[x]+=r[y];
43 }
44 return 1;
45 }
46
47 inline void add_edge(int from,int to)
48 {
49 e[ne].to=to;
50 e[ne].next=head[from];
51 head[from]=&e[ne++];
52 }
53
54 int main()
55 {
56 scanf("%d%d",&n,&m);
57 for (int i=1;i<=m;i++)
58 {
59 int x,y;
60 scanf("%d%d",&x,&y);
61 add_edge(x,y);
62 add_edge(y,x);
63 }
64 for (int i=0;i<n;i++)
65 flag[i]=1;
66 int k;
67 scanf("%d",&k);
68 for (int i=1;i<=k;i++)
69 {
70 scanf("%d",&des[i]);
71 flag[des[i]]=0;
72 }
73 int size=0;
74 for (int i=0;i<n;i++)
75 f[i]=i;
76 for (int i=0;i<n;i++)
77 if (flag[i])
78 size++;
79 for (int i=0;i<n;i++)
80 if (flag[i])
81 for (edge *p=head[i];p;p=p->next)
82 if (flag[p->to])
83 size-=_union(i,p->to);
84 ans[k]=size;
85 for (int i=k;i;i--)
86 {
87 if (!flag[des[i]])
88 size++;
89 flag[des[i]]=1;
90 for (edge *p=head[des[i]];p;p=p->next)
91 if (flag[p->to])
92 size-=_union(des[i],p->to);
93 ans[i-1]=size;
94 }
95 for (int i=0;i<=k;i++)
96 printf("%d
",ans[i]);
97 return 0;
98 }
View Code
bzoj1024
爆搜
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 20
7
8 double ans=1e+18;
9
10 inline double dfs(double x,double y,int rem)
11 {
12 if (x < y)
13 swap(x,y);
14 if (rem == 1)
15 return x/y;
16 double now=1e+18;
17 double r=1/(double)rem;
18 for (int i=1;i<rem;i++)
19 {
20 now=min(now,max(dfs(x*r*i,y,i),dfs(x-x*r*i,y,rem-i)));
21 now=min(now,max(dfs(x,y*r*i,i),dfs(x,y-y*r*i,rem-i)));
22 }
23 return now;
24 }
25
26 int main()
27 {
28 double x,y;
29 int n;
30 scanf("%lf%lf%d",&x,&y,&n);
31 printf("%.6lf
",dfs(x,y,n));
32 return 0;
33 }
View Code
bzoj1026
水水的数位DP
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 15
7
8 int bit[maxn];
9 int f[maxn][10];
10
11 inline int calc(int n)
12 {
13 if (!n)
14 return 0;
15 int ans=0,len=10;
16 while (bit[len] > n)
17 len--;
18 for (int i=1;i<len;i++)
19 for (int j=1;j<=9;j++)
20 ans+=f[i][j];
21 int rest=n/bit[len];
22 for (int i=1;i<rest;i++)
23 ans+=f[len][i];
24 int pre=rest;
25 n%=bit[len];
26 for (int i=len-1;i;i--)
27 {
28 rest=n/bit[i];
29 if (i != 1)
30 {
31 for (int j=0;j<rest;j++)
32 if (abs(pre-j) >= 2)
33 ans+=f[i][j];
34 }
35 else
36 {
37 for (int j=0;j<=rest;j++)
38 if (abs(pre-j) >= 2)
39 ans+=f[i][j];
40 }
41 if (abs(rest-pre) < 2)
42 break;
43 pre=rest;
44 n%=bit[i];
45 }
46 return ans;
47 }
48
49 int main()
50 {
51 bit[1]=1;
52 for (int i=2;i<=10;i++)
53 bit[i]=bit[i-1]*10;
54 for (int i=0;i<=9;i++)
55 f[1][i]=1;
56 for (int i=2;i<=10;i++)
57 for (int j=0;j<=9;j++)
58 for (int k=0;k<=9;k++)
59 if (abs(j-k) >= 2)
60 f[i][j]+=f[i-1][k];
61 int a,b;
62 scanf("%d%d",&a,&b);
63 printf("%d
",calc(b)-calc(a-1));
64 return 0;
65 }
View Code
bzoj1029
开个堆乱搞即可
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
#define maxn 1000010
pair <int,int> a[maxn];
inline void read(int &x)
{
char ch;
while (ch=getchar(),ch > '9' || ch < '0');
x=ch-'0';
while (ch=getchar(),ch <= '9' && ch >= '0')
x=(x<<3)+x+x+ch-'0';
}
priority_queue <int> q;
int main()
{
int n;
read(n);
for (int i=1;i<=n;i++)
{
read(a[i].second);
read(a[i].first);
}
sort(a+1,a+n+1);
int now=0,ans=0;
for (int i=1;i<=n;i++)
if (now+a[i].second <= a[i].first)
{
now+=a[i].second;
ans++;
q.push(a[i].second);
}
else
if (q.top() > a[i].second)
{
now-=q.top()-a[i].second;
q.pop();
q.push(a[i].second);
}
printf("%d
",ans);
return 0;
}
View Code
bzoj1030
AC自动机+DP
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxl 110
5 #define maxn 6010
6 #define mod 10007
7
8 struct Node
9 {
10 bool end;
11 Node *s[26],*fail;
12
13 inline Node()
14 {
15 end=0;
16 fail=NULL;
17 for (int i=0;i<26;i++)
18 s[i]=NULL;
19 }
20 }t[maxn],*root,*q[maxn];
21
22 int ne=0;
23 char s[maxl];
24
25 inline void init()
26 {
27 root=&t[0];
28 root->fail=root;
29 ne=1;
30 }
31
32 inline void insert(char* s)
33 {
34 Node* now=root;
35 int l=strlen(s);
36 for (int i=0;i<l;i++)
37 {
38 int p=s[i]-'A';
39 if (now->s[p] == NULL)
40 now->s[p]=&t[ne++];
41 now=now->s[p];
42 }
43 now->end=1;
44 }
45
46 inline void build()
47 {
48 int op=0,cls=1;
49 q[1]=root;
50 for (int i=0;i<26;i++)
51 if (root->s[i] == NULL)
52 root->s[i]=root;
53 while (op != cls)
54 {
55 Node* now=q[++op];
56 for (int i=0;i<26;i++)
57 if (now->s[i] != NULL)
58 {
59 if (now->s[i] != root)
60 q[++cls]=now->s[i];
61 if (now != root)
62 {
63 now->s[i]->fail=now->fail->s[i];
64 now->s[i]->end|=now->s[i]->fail->end;
65 }
66 else
67 now->s[i]->fail=root;
68 }
69 else
70 now->s[i]=now->fail->s[i];
71 }
72 }
73
74 int f[maxl][maxn][2];
75
76 int main()
77 {
78 int n,m;
79 scanf("%d%d",&n,&m);
80 init();
81 for (int i=1;i<=n;i++)
82 {
83 scanf("%s",s);
84 insert(s);
85 }
86 build();
87 f[0][0][0]=1;
88 for (int i=0;i<m;i++)
89 for (int j=0;j<ne;j++)
90 for (int k=0;k<2;k++)
91 {
92 Node* now=&t[j];
93 for (int l=0;l<26;l++)
94 (f[i+1][now->s[l]-t][k|now->s[l]->end]+=f[i][j][k])%=mod;
95 }
96 int ans=0;
97 for (int i=0;i<ne;i++)
98 (ans+=f[m][i][1])%=mod;
99 printf("%d
",ans);
100 return 0;
101 }
View Code
bzoj1031
不用height的后缀数组。。。
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 200010
5
6 char ch[maxn];
7 int a[maxn];
8 int sa[maxn];
9
10 int wa[maxn],wb[maxn],wv[maxn],ws[maxn];
11
12 inline int cmp(int *r,int a,int b,int l)
13 {return r[a]==r[b]&&r[a+l]==r[b+l];}
14
15 inline void da(int *r,int *sa,int n,int m)
16 {
17 int i,j,p,*x=wa,*y=wb,*t;
18 for(i=0;i<m;i++) ws[i]=0;
19 for(i=0;i<n;i++) ws[x[i]=r[i]]++;
20 for(i=1;i<m;i++) ws[i]+=ws[i-1];
21 for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;
22 for(j=1,p=1;p<n;j*=2,m=p)
23 {
24 for(p=0,i=n-j;i<n;i++) y[p++]=i;
25 for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
26 for(i=0;i<n;i++) wv[i]=x[y[i]];
27 for(i=0;i<m;i++) ws[i]=0;
28 for(i=0;i<n;i++) ws[wv[i]]++;
29 for(i=1;i<m;i++) ws[i]+=ws[i-1];
30 for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];
31 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
32 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
33 }
34 return;
35 }
36
37 int rank[maxn],height[maxn];
38
39 inline void calheight(int *r,int *sa,int n)
40 {
41 int i,j,k=0;
42 for(i=1;i<=n;i++) rank[sa[i]]=i;
43 for(i=0;i<n;height[rank[i++]]=k)
44 for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
45 return;
46 }
47
48 int main()
49 {
50 scanf("%s",ch);
51 int len=strlen(ch);
52 for (int i=0;i<len;i++)
53 {
54 a[i]=a[i+len]=ch[i];
55 ch[i+len]=ch[i];
56 }
57 len<<=1;
58 da(a,sa,len+1,200);
59 len>>=1;
60 for (int i=1;i<=len<<1;i++)
61 if (sa[i] < len)
62 printf("%c",ch[sa[i]+len-1]);
63 return 0;
64 }
View Code
bzoj1034
排序,然后两边往中间扫即可,想想田忌是怎么赢的,思想是贪心
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 100010
7
8 int a[maxn],b[maxn];
9
10 inline void read(int &x)
11 {
12 char ch;
13 while (ch=getchar(),ch > '9' || ch < '0');
14 x=ch-'0';
15 while (ch=getchar(),ch <= '9' && ch >= '0')
16 x=(x<<3)+x+x+ch-'0';
17 }
18
19 int main()
20 {
21 int n;
22 read(n);
23 for (int i=1;i<=n;i++)
24 read(a[i]);
25 for (int i=1;i<=n;i++)
26 read(b[i]);
27 sort(a+1,a+n+1);
28 sort(b+1,b+n+1);
29 int al=1,ar=n,bl=1,br=n,ans=0;
30 while (al <= ar && bl <= br)
31 {
32 if (a[al] > b[bl])
33 {
34 ans+=2;
35 al++;
36 bl++;
37 }
38 else
39 {
40 if (a[ar] > b[br])
41 {
42 ans+=2;
43 ar--;
44 br--;
45 }
46 else
47 {
48 ans+=a[al] == b[br];
49 al++;
50 br--;
51 }
52 }
53 }
54 printf("%d ",ans);
55 al=bl=1,ar=br=n,ans=0;
56 while (al <= ar && bl <= br)
57 {
58 if (b[bl] > a[al])
59 {
60 ans+=2;
61 al++;
62 bl++;
63 }
64 else
65 {
66 if (b[br] > a[ar])
67 {
68 ans+=2;
69 ar--;
70 br--;
71 }
72 else
73 {
74 ans+=a[ar] == b[bl];
75 bl++;
76 ar--;
77 }
78 }
79 }
80 printf("%d
",2*n-ans);
81 return 0;
82 }
View Code
bzoj1036
lct模板题,注意null结点的初始值
1 #include <cstdio>
2
3 #define maxn 30010
4 #define inf 0x3f3f3f3f
5
6 struct Node
7 {
8 int v,max,sum;
9 bool rt;
10 Node* s[2],*par;
11 }t[maxn],null;
12
13 struct edge
14 {
15 int to;
16 edge *next;
17 }e[maxn<<1],*head[maxn];
18
19 int ne=0;
20 int q[maxn];
21 bool vis[maxn];
22
23 inline void add_edge(int from,int to)
24 {
25 e[ne].to=to;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 inline void bfs()
31 {
32 int op=0,cls=1;
33 q[1]=1;
34 vis[1]=1;
35 while (op != cls)
36 {
37 int x=q[++op];
38 for (edge *p=head[x];p;p=p->next)
39 if (!vis[p->to])
40 {
41 q[++cls]=p->to;
42 vis[p->to]=1;
43 t[p->to].par=&t[x];
44 }
45 }
46 }
47
48 inline int max(int a,int b)
49 {
50 return a > b ? a : b;
51 }
52
53 inline void _update(Node* now)
54 {
55 now->sum=now->s[0]->sum+now->s[1]->sum+now->v;
56 now->max=max(max(now->s[0]->max,now->s[1]->max),now->v);
57 }
58
59 inline void _rot(Node* now,int l)
60 {
61 int r=!l;
62 Node* p=now->par;
63 Node* s=now->s[l];
64 (now->s[l]=s->s[r])->par=now;
65 (s->s[r]=now)->par=s;
66 s->par=p;
67 if (!now->rt)
68 p->s[now == p->s[1]]=s;
69 else
70 {
71 now->rt=0;
72 s->rt=1;
73 }
74 _update(now);
75 _update(s);
76 }
77
78 inline void _splay(Node* now)
79 {
80 while (!now->rt)
81 {
82 Node* p=now->par;
83 Node* g=p->par;
84 bool dp=now == p->s[1];
85 bool dg=p == g->s[1];
86 if (p->rt)
87 {
88 _rot(p,dp);
89 return;
90 }
91 if (dp == dg)
92 {
93 _rot(g,dg);
94 _rot(p,dp);
95 }
96 else
97 {
98 _rot(p,dp);
99 _rot(g,dg);
100 }
101 }
102 }
103
104 inline void access(Node* now)
105 {
106 Node* p=now;
107 Node* q=&null;
108 do
109 {
110 _splay(p);
111 if (p->s[1] != &null)
112 p->s[1]->rt=1;
113 p->s[1]=q;
114 if (q != &null)
115 {
116 q->par=p;
117 q->rt=0;
118 }
119 _update(p);
120 q=p;
121 p=p->par;
122 }
123 while (p != &null);
124 }
125
126 inline Node* doit(Node* now)
127 {
128 Node* p;
129 _splay(now);
130 if (now->s[0] != &null)
131 {
132 for (p=now->s[0];p->s[1] != &null;p=p->s[1]);
133 _splay(p);
134 }
135 return now;
136 }
137
138 inline int qsum(Node* u,Node* v)
139 {
140 access(u);
141 _splay(v);
142 if (v->par == &null)
143 return doit(v)->sum;
144 access(v);
145 _splay(u);
146 if (u->par == &null)
147 return doit(u)->sum;
148 return u->sum+doit(u->par)->sum;
149 }
150
151 inline int qmax(Node* u,Node* v)
152 {
153 access(u);
154 _splay(v);
155 if (v->par == &null)
156 return doit(v)->max;
157 access(v);
158 _splay(u);
159 if (u->par == &null)
160 return doit(u)->max;
161 return max(u->max,doit(u->par)->max);
162 }
163
164 inline void change(Node* now,int v)
165 {
166 _splay(now);
167 now->v=v;
168 _update(now);
169 }
170
171 int main()
172 {
173 null.s[0]=null.s[1]=null.par=&null;
174 null.max=-inf;null.sum=null.v=0;
175 null.rt=1;
176 int n;
177 scanf("%d",&n);
178 for (int i=1;i<n;i++)
179 {
180 int x,y;
181 scanf("%d%d",&x,&y);
182 add_edge(x,y);
183 add_edge(y,x);
184 }
185 for (int i=1;i<=n;i++)
186 {
187 scanf("%d",&t[i].v);
188 t[i].s[0]=t[i].s[1]=t[1].par=&null;
189 t[i].rt=1;
190 t[i].max=t[i].sum=t[i].v;
191 }
192 bfs();
193 int _;
194 char s[10];
195 scanf("%d",&_);
196 while (_--)
197 {
198 int x,y;
199 scanf("%s%d%d",s,&x,&y);
200 if (s[0] == 'C')
201 change(&t[x],y);
202 else
203 {
204 if (s[1] == 'M')
205 printf("%d
",qmax(&t[x],&t[y]));
206 else
207 printf("%d
",qsum(&t[x],&t[y]));
208 }
209 }
210 return 0;
211 }
View Code
bzoj1042
背包+容斥
1 #include <cstdio>
2
3 #define maxn 100010
4
5 int bit[10];
6 int c[4],d[4];
7 long long f[maxn];
8
9 inline void pre()
10 {
11 f[0]=1;
12 for (int i=0;i<4;i++)
13 for (int j=c[i];j<maxn;j++)
14 f[j]+=f[j-c[i]];
15 }
16
17 inline long long calc(int v)
18 {
19 long long ans=f[v];
20 for (int i=1;i<=15;i++)
21 {
22 int sum=0,nowv=v;
23 for (int j=0;j<4;j++)
24 if (i&bit[j])
25 {
26 nowv-=(d[j]+1)*c[j];
27 sum++;
28 }
29 if (nowv < 0)
30 continue;
31 if (sum&1)
32 ans-=f[nowv];
33 else
34 ans+=f[nowv];
35 }
36 return ans;
37 }
38
39 int main()
40 {
41 bit[0]=1;
42 for (int i=1;i<=5;i++)
43 bit[i]=bit[i-1]+bit[i-1];
44 int _;
45 for (int i=0;i<4;i++)
46 scanf("%d",&c[i]);
47 pre();
48 scanf("%d",&_);
49 while (_--)
50 {
51 int v;
52 for (int i=0;i<4;i++)
53 scanf("%d",&d[i]);
54 scanf("%d",&v);
55 printf("%lld
",calc(v));
56 }
57 return 0;
58 }
View Code
bzoj1045
排序后往中位数方向传递(大概就是这个意思吧。。。)可以直接算答案
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 1000010
7
8 #ifdef unix
9 #define LL "%lld"
10 #else
11 #define LL "%I64d"
12 #endif
13
14 inline void read(long long &x)
15 {
16 char ch;
17 while (ch=getchar(),ch > '9' || ch < '0');
18 x=ch-'0';
19 while (ch=getchar(),ch <= '9' && ch >= '0')
20 x=(x<<3)+x+x+ch-'0';
21 }
22
23 long long d[maxn];
24
25 int main()
26 {
27 long long n,sum=0;
28 read(n);
29 for (long long i=1;i<=n;i++)
30 {
31 read(d[i]);
32 sum+=d[i];
33 }
34 sum/=n;
35 for (long long i=1;i<=n;i++)
36 d[i]=d[i-1]+d[i]-sum;
37 sort(d+1,d+n+1);
38 long long ans=0,now=d[(n+1)>>1];
39 for (long long i=1;i<=n;i++)
40 ans+=abs(d[i]-now);
41 printf(LL,ans);
42 return 0;
43 }
View Code
bzoj1046
nlogn的最长上升序列,后面的询问可以直接用f数组来搞
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 10010
7
8 int n,m,size;
9 int t[maxn<<2];
10 int a[maxn],b[maxn],f[maxn];
11 int ans[maxn];
12
13 inline void _update(int rt)
14 {
15 t[rt]=max(t[rt<<1],t[rt<<1|1]);
16 }
17
18 void insert(int l,int r,int rt,int pos,int val)
19 {
20 if (l == r)
21 {
22 t[rt]=max(t[rt],val);
23 return;
24 }
25 int mid=(l+r)>>1;
26 if (pos <= mid)
27 insert(l,mid,rt<<1,pos,val);
28 else
29 insert(mid+1,r,rt<<1|1,pos,val);
30 _update(rt);
31 }
32
33 int query(int l,int r,int rt,int L,int R)
34 {
35 if (l >= L && r <= R)
36 return t[rt];
37 int mid=(l+r)>>1,ans=0;
38 if (L <= mid)
39 ans=max(ans,query(l,mid,rt<<1,L,R));
40 if (R > mid)
41 ans=max(ans,query(mid+1,r,rt<<1|1,L,R));
42 return ans;
43 }
44
45 int main()
46 {
47 scanf("%d",&n);
48 for (int i=1;i<=n;i++)
49 {
50 scanf("%d",&a[i]);
51 b[i]=a[i];
52 }
53 sort(b+1,b+n+1);
54 size=unique(b+1,b+n+1)-b-1;
55 for (int i=1;i<=n;i++)
56 a[i]=lower_bound(b+1,b+size+1,a[i])-b;
57 f[n]=1;
58 insert(1,size,1,a[n],1);
59 int _max=0;
60 for (int i=n-1;i;i--)
61 {
62 f[i]=query(1,size,1,a[i]+1,size)+1;
63 _max=max(f[i],_max);
64 insert(1,size,1,a[i],f[i]);
65 }
66 scanf("%d",&m);
67 while (m--)
68 {
69 int x;
70 scanf("%d",&x);
71 if (x > _max)
72 {
73 puts("Impossible");
74 continue;
75 }
76 int now=0,sum=x,prev=0,cnt=0;
77 for (int i=1;i<=n;i++)
78 if (f[i] >= x)
79 {
80 now=i;
81 prev=a[i];
82 ans[++cnt]=b[a[i]];
83 sum--;
84 break;
85 }
86 for (int i=now+1;i<=n;i++)
87 {
88 if (f[i] >= sum && a[i] > prev)
89 {
90 sum--;
91 prev=a[i];
92 ans[++cnt]=b[a[i]];
93 }
94 if (!sum)
95 break;
96 }
97 for (int i=1;i<x;i++)
98 printf("%d ",ans[i]);
99 printf("%d
",ans[x]);
100 }
101 return 0;
102 }
View Code
bzoj1047
单调队列,经典的滑窗问题
1 #include <cstdio>
2 #include <queue>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 1010
8 #define inf 0x3f3f3f3f
9
10 deque <pair<int,int> > q;
11
12 int num[maxn][maxn],_max[maxn][maxn],_min[maxn][maxn];
13 int ans_max[maxn][maxn],ans_min[maxn][maxn];
14
15 inline void read(int &x)
16 {
17 char ch;
18 while (ch=getchar(),ch > '9' || ch < '0');
19 x=ch-'0';
20 while (ch=getchar(),ch <= '9' && ch >= '0')
21 x=(x<<3)+x+x+ch-'0';
22 }
23
24 int main()
25 {
26 int a,b,n;
27 read(a);
28 read(b);
29 read(n);
30 for (int i=1;i<=a;i++)
31 for (int j=1;j<=b;j++)
32 read(num[i][j]);
33 for (int i=1;i<=a;i++)
34 {
35 while (!q.empty())
36 q.pop_front();
37 for (int j=1;j<=n;j++)
38 {
39 while (!q.empty() && q.back().first < num[i][j])
40 q.pop_back();
41 q.push_back(make_pair(num[i][j],j));
42 }
43 _max[i][n]=q.front().first;
44 for (int j=n+1;j<=b;j++)
45 {
46 if (q.front().second < j-n+1)
47 q.pop_front();
48 while (!q.empty() && q.back().first < num[i][j])
49 q.pop_back();
50 q.push_back(make_pair(num[i][j],j));
51 _max[i][j]=q.front().first;
52 }
53 }
54 for (int i=1;i<=a;i++)
55 {
56 while (!q.empty())
57 q.pop_front();
58 for (int j=1;j<=n;j++)
59 {
60 while (!q.empty() && q.back().first > num[i][j])
61 q.pop_back();
62 q.push_back(make_pair(num[i][j],j));
63 }
64 _min[i][n]=q.front().first;
65 for (int j=n+1;j<=b;j++)
66 {
67 if (q.front().second < j-n+1)
68 q.pop_front();
69 while (!q.empty() && q.back().first > num[i][j])
70 q.pop_back();
71 q.push_back(make_pair(num[i][j],j));
72 _min[i][j]=q.front().first;
73 }
74 }
75 for (int i=n;i<=b;i++)
76 {
77 while (!q.empty())
78 q.pop_front();
79 for (int j=1;j<=n;j++)
80 {
81 while (!q.empty() && q.back().first < _max[j][i])
82 q.pop_back();
83 q.push_back(make_pair(_max[j][i],j));
84 }
85 ans_max[n][i]=q.front().first;
86 for (int j=n+1;j<=a;j++)
87 {
88 if (q.front().second < j-n+1)
89 q.pop_front();
90 while (!q.empty() && q.back().first < _max[j][i])
91 q.pop_back();
92 q.push_back(make_pair(_max[j][i],j));
93 ans_max[j][i]=q.front().first;
94 }
95 }
96 for (int i=n;i<=b;i++)
97 {
98 while (!q.empty())
99 q.pop_front();
100 for (int j=1;j<=n;j++)
101 {
102 while (!q.empty() && q.back().first > _min[j][i])
103 q.pop_back();
104 q.push_back(make_pair(_min[j][i],j));
105 }
106 ans_min[n][i]=q.front().first;
107 for (int j=n+1;j<=a;j++)
108 {
109 if (q.front().second < j-n+1)
110 q.pop_front();
111 while (!q.empty() && q.back().first > _min[j][i])
112 q.pop_back();
113 q.push_back(make_pair(_min[j][i],j));
114 ans_min[j][i]=q.front().first;
115 }
116 }
117 int ans=inf;
118 for (int i=n;i<=a;i++)
119 for (int j=n;j<=b;j++)
120 if (ans_max[i][j]-ans_min[i][j] < ans)
121 ans=ans_max[i][j]-ans_min[i][j];
122 printf("%d
",ans);
123 return 0;
124 }
View Code
bzoj1051
tarjan缩点之后统计出度为0的点的个数
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 20010
7 #define maxm 50010
8
9 struct edge
10 {
11 int to;
12 edge *next;
13 }e[maxm],*head[maxn];
14
15 int ne=0,time=0,top=0,cnt;
16 int dfn[maxn],sta[maxn],low[maxn],belong[maxn],size[maxn];
17 int in[maxn],out[maxn];
18 bool vis[maxn];
19
20 inline void add_edge(int from,int to)
21 {
22 e[ne].to=to;
23 e[ne].next=head[from];
24 head[from]=&e[ne++];
25 }
26
27 void tarjan(int now)
28 {
29 dfn[now]=low[now]=++time;
30 sta[++top]=now;
31 vis[now]=1;
32 for (edge *p=head[now];p;p=p->next)
33 if (!dfn[p->to])
34 {
35 tarjan(p->to);
36 low[now]=min(low[now],low[p->to]);
37 }
38 else
39 if (vis[p->to])
40 low[now]=min(low[now],dfn[p->to]);
41 if (dfn[now] == low[now])
42 {
43 int v;
44 cnt++;
45 do
46 {
47 v=sta[top--];
48 vis[v]=0;
49 belong[v]=cnt;
50 size[cnt]++;
51 }
52 while (v != now);
53 }
54 }
55
56 int main()
57 {
58 int n,m;
59 scanf("%d%d",&n,&m);
60 for (int i=1;i<=m;i++)
61 {
62 int x,y;
63 scanf("%d%d",&x,&y);
64 add_edge(x,y);
65 }
66 cnt=n;
67 for (int i=1;i<=n;i++)
68 if (!dfn[i])
69 tarjan(i);
70 for (int i=1;i<=n;i++)
71 for (edge *p=head[i];p;p=p->next)
72 if (belong[i] != belong[p->to])
73 {
74 in[belong[p->to]]++;
75 out[belong[i]]++;
76 add_edge(belong[i],belong[p->to]);
77 }
78 int now=0;
79 for (int i=n+1;i<=cnt;i++)
80 if (!out[i])
81 now++;
82 if (now >= 2)
83 {
84 puts("0");
85 return 0;
86 }
87 for (int i=n+1;i<=cnt;i++)
88 if (!out[i])
89 {
90 printf("%d
",size[i]);
91 return 0;
92 }
93 return 0;
94 }
View Code
bzoj1052
遮四个角落一定最优,二分边长,然后递归两层枚举遮哪一个角落,第三层check
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 20010
8 #define inf 0x3f3f3f3f
9
10 int n;
11 int x[maxn],y[maxn],mx[2]={inf,-inf},my[2]={inf,-inf};
12 bool flag[maxn];
13
14 inline bool check(int r)
15 {
16 for (int i=0;i<2;i++)
17 for (int j=0;j<2;j++)
18 {
19 memset(flag,1,sizeof(flag));
20 int now=0,nowx=mx[i],nowy=my[j],nowmx[2]={inf,-inf},nowmy[2]={inf,-inf};
21 for (int k=1;k<=n;k++)
22 if (abs(x[k]-nowx) <= r && abs(y[k]-nowy) <= r)
23 {
24 flag[k]=0;
25 now++;
26 if (now == n)
27 return 1;
28 }
29 else
30 {
31 nowmx[0]=min(nowmx[0],x[k]);
32 nowmy[0]=min(nowmy[0],y[k]);
33 nowmx[1]=max(nowmx[1],x[k]);
34 nowmy[1]=max(nowmy[1],y[k]);
35 }
36 for (int k=0;k<2;k++)
37 for (int l=0;l<2;l++)
38 {
39 int sum=now;
40 nowx=nowmx[k];
41 nowy=nowmy[l];
42 int max_x=-inf,max_y=-inf,min_x=inf,min_y=inf;
43 for (int m=1;m<=n;m++)
44 if (flag[m])
45 {
46 if (abs(x[m]-nowx) <= r && abs(y[m]-nowy) <= r)
47 {
48 sum++;
49 if (sum == n)
50 return 1;
51 }
52 else
53 {
54 max_x=max(max_x,x[m]);
55 max_y=max(max_y,y[m]);
56 min_x=min(min_x,x[m]);
57 min_y=min(min_y,y[m]);
58 }
59 }
60 if (max_x-min_x <= r && max_y-min_y <= r)
61 return 1;
62 }
63 }
64 return 0;
65 }
66
67 inline void read(int &x)
68 {
69 char ch;
70 bool flag=0;
71 while (ch=getchar(),(ch > '9' || ch < '0') && (ch != '-'));
72 if (ch == '-')
73 flag=1;
74 else
75 x=ch-'0';
76 while (ch=getchar(),ch <= '9' && ch >= '0')
77 x=(x<<3)+x+x+ch-'0';
78 if (flag)
79 x=-x;
80 }
81
82 int main()
83 {
84 read(n);
85 for (int i=1;i<=n;i++)
86 {
87 read(x[i]);
88 read(y[i]);
89 mx[1]=max(mx[1],x[i]);
90 my[1]=max(my[1],y[i]);
91 mx[0]=min(mx[0],x[i]);
92 my[0]=min(my[0],y[i]);
93 }
94 int l=0,r=inf,ans=0;
95 while (l < r)
96 {
97 int mid=(l+r)>>1;
98 if (check(mid))
99 ans=r=mid;
100 else
101 l=mid+1;
102 }
103 printf("%d
",ans);
104 return 0;
105 }
View Code
bzoj1058
正解我不会。。。写了两颗SBT来暴力,加了些优化还是能12s的
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 1500010
7 #define inf 0x3f3f3f3f
8
9 struct Node
10 {
11 int v,size;
12 Node *s[2];
13
14 Node()
15 {
16 size=1;
17 }
18 };
19
20 struct sbt
21 {
22 Node t[maxn],null;
23 Node *root;
24 int ne;
25
26 inline sbt()
27 {
28 null.s[0]=null.s[1]=&null;
29 null.size=0;
30 root=&null;
31 ne=0;
32 }
33
34 inline void _update(Node* now)
35 {
36 now->size=now->s[0]->size+now->s[1]->size+1;
37 }
38
39 inline Node* new_Node()
40 {
41 Node* now=&t[ne++];
42 now->s[0]=now->s[1]=&null;
43 return now;
44 }
45
46 inline void _rot(Node* &now,int l)
47 {
48 int r=!l;
49 Node* s=now->s[l];
50 now->s[l]=s->s[r];
51 s->s[r]=now;
52 _update(now);
53 _update(s);
54 now=s;
55 }
56
57 void _maintain(Node* &now,int l)
58 {
59 int r=!l;
60 if (now->s[l]->s[l]->size > now->s[r]->size)
61 _rot(now,l);
62 else
63 if (now->s[l]->s[r]->size > now->s[r]->size)
64 {
65 _rot(now->s[l],r);
66 _rot(now,l);
67 }
68 else
69 return;
70 _maintain(now->s[0],0);
71 _maintain(now->s[1],1);
72 _maintain(now,0);
73 _maintain(now,1);
74 }
75
76 void insert(Node* &now,int v)
77 {
78 if (now == &null)
79 {
80 now=new_Node();
81 now->v=v;
82 return;
83 }
84 now->size++;
85 insert(now->s[v >= now->v],v);
86 _maintain(now,v >= now->v);
87 }
88
89 int del(Node* &now,int v)
90 {
91 now->size--;
92 if ((now->v == v) || (v < now->v && now->s[0] == &null) || (v > now->v && now->s[1] == &null))
93 {
94 int t=now->v;
95 if (now->s[0] == &null)
96 now=now->s[1];
97 else
98 if (now->s[1] == &null)
99 now=now->s[0];
100 else
101 now->v=del(now->s[1],0);
102 return t;
103 }
104 else
105 del(now->s[v > now->v],v);
106 }
107
108 inline Node* _select(int v)
109 {
110 Node* now=root;
111 while (v)
112 {
113 if (now->s[0]->size+1 == v)
114 return now;
115 if (v <= now->s[0]->size)
116 now=now->s[0];
117 else
118 {
119 v-=now->s[0]->size+1;
120 now=now->s[1];
121 }
122 }
123 }
124
125 inline int pred(int v)
126 {
127 Node* now=root;
128 int ans=-inf;
129 while (1)
130 {
131 if (now == &null)
132 return ans;
133 if (now->v <= v)
134 {
135 ans=now->v;
136 now=now->s[1];
137 }
138 else
139 now=now->s[0];
140 }
141 return ans;
142 }
143
144 inline int succ(int v)
145 {
146 Node* now=root;
147 int ans=inf;
148 while (1)
149 {
150 if (now == &null)
151 return ans;
152 if (now->v >= v)
153 {
154 ans=now->v;
155 now=now->s[0];
156 }
157 else
158 now=now->s[1];
159 }
160 return ans;
161 }
162
163 inline int get_min()
164 {
165 int ans=inf;
166 Node* now=root;
167 while (1)
168 {
169 if (now == &null)
170 return ans;
171 ans=now->v;
172 now=now->s[0];
173 }
174 }
175
176 void travel(Node* now)
177 {
178 if (now->s[0] != &null)
179 travel(now->s[0]);
180 printf("%d ",now->v);
181 if (now->s[1] != &null)
182 travel(now->s[1]);
183 }
184 }t1,t2;
185
186 struct xxx
187 {
188 int begin,end;
189 }a[maxn];
190
191 int main()
192 {
193 //freopen("form.in","r",stdin);
194 //freopen("form.out","w",stdout);
195 int n,_;
196 scanf("%d%d",&n,&_);
197 int now_min=inf,crf_min=inf;
198 for (int i=1;i<=n;i++)
199 {
200 scanf("%d",&a[i].begin);
201 a[i].end=a[i].begin;
202 now_min=min(now_min,abs(a[i].begin-t1.pred(a[i].begin)));
203 now_min=min(now_min,abs(t1.succ(a[i].begin)-a[i].begin));
204 t1.insert(t1.root,a[i].begin);
205 if (i != 1)
206 t2.insert(t2.root,abs(a[i].begin-a[i-1].end));
207 }
208 crf_min=t2.get_min();
209 while (_--)
210 {
211 char s[20];
212 int x,y;
213 scanf("%s",s);
214 if (s[0] == 'I')
215 {
216 scanf("%d%d",&x,&y);
217 if (x != n)
218 {
219 t2.del(t2.root,abs(a[x].end-a[x+1].begin));
220 t2.insert(t2.root,abs(y-a[x+1].begin));
221 }
222 t2.insert(t2.root,abs(y-a[x].end));
223 crf_min=t2.get_min();
224 a[x].end=y;
225 if (now_min)
226 {
227 now_min=min(now_min,abs(y-t1.pred(y)));
228 now_min=min(now_min,abs(t1.succ(y)-y));
229 t1.insert(t1.root,y);
230 }
231 }
232 if (s[0] == 'M' && s[4] == 'G')
233 printf("%d
",crf_min);
234 if (s[0] == 'M' && s[4] == 'S')
235 printf("%d
",now_min);
236 }
237 return 0;
238 }
View Code
bzoj1059
二分图匹配,行匹配列
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 410
8 #define maxm 40010
9 #define s 0
10 #define t maxn-1
11 #define inf 0x3f3f3f3f
12
13 struct edge
14 {
15 int to,flow;
16 edge *next,*part;
17 }e[maxm<<1],*head[maxn];
18
19 int ne=0;
20 int q[maxn],d[maxn];
21
22 inline void add(int from,int to,int flow)
23 {
24 e[ne].to=to;
25 e[ne].flow=flow;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 inline void add_edge(int from,int to,int flow)
31 {
32 e[ne].part=&e[ne+1];
33 e[ne+1].part=&e[ne];
34 add(from,to,flow);
35 add(to,from,0);
36 }
37
38 inline bool bfs()
39 {
40 int op=0,cls=1;
41 memset(d,-1,sizeof(d));
42 q[1]=s;
43 d[s]=0;
44 while (op != cls)
45 {
46 int x=q[++op];
47 for (edge *p=head[x];p;p=p->next)
48 if (p->flow && d[p->to] == -1)
49 {
50 q[++cls]=p->to;
51 d[p->to]=d[x]+1;
52 }
53 }
54 return d[t] != -1;
55 }
56
57 int dfs(int now,int now_flow)
58 {
59 if (now == t)
60 return now_flow;
61 int out=now_flow;
62 for (edge *p=head[now];p;p=p->next)
63 if (p->flow && d[p->to] == d[now]+1 && out)
64 {
65 int f=dfs(p->to,min(p->flow,out));
66 p->flow-=f;
67 p->part->flow+=f;
68 out-=f;
69 }
70 if (out == now_flow)
71 d[now]=-1;
72 return now_flow-out;
73 }
74
75 inline int dinic()
76 {
77 int ans=0;
78 while (bfs())
79 ans+=dfs(s,inf);
80 return ans;
81 }
82
83 int main()
84 {
85 int _;
86 scanf("%d",&_);
87 while (_--)
88 {
89 memset(head,0x0,sizeof(head));
90 ne=0;
91 int n;
92 scanf("%d",&n);
93 for (int i=1;i<=n;i++)
94 for (int j=1;j<=n;j++)
95 {
96 int x;
97 scanf("%d",&x);
98 if (x)
99 add_edge(i,j+n,1);
100 }
101 for (int i=1;i<=n;i++)
102 {
103 add_edge(s,i,1);
104 add_edge(i+n,t,1);
105 }
106 int ans=dinic();
107 if (ans == n)
108 puts("Yes");
109 else
110 puts("No");
111 }
112 return 0;
113 }
View Code
bzoj1061
神一般的费用流转化,具体参见byvoid神犇的博客。。。后来会了单纯形也没重新来写这道题,就贴费用流代码吧
1 #include <cstdio>
2 #include <cstring>
3 #include <queue>
4 #include <algorithm>
5 #include <bitset>
6
7 using namespace std;
8
9 #define maxn 1010
10 #define maxm 1000010
11 #define inf 0x3f3f3f3f
12
13 struct edge
14 {
15 int to,flow,cost;
16 edge *part,*next;
17 }e[maxm<<1],*head[maxn],*prev[maxn];
18
19 int ne=0;
20 int s=0,t=maxn-1;
21 int d[maxn],q[maxn];
22 bitset <maxn> flag;
23
24 inline void add(int from,int to,int flow,int cost)
25 {
26 e[ne].to=to;
27 e[ne].flow=flow;
28 e[ne].cost=cost;
29 e[ne].next=head[from];
30 head[from]=&e[ne++];
31 }
32
33 inline void add_edge(int from,int to,int flow,int cost)
34 {
35 e[ne].part=&e[ne+1];
36 e[ne+1].part=&e[ne];
37 add(from,to,flow,cost);
38 add(to,from,0,-cost);
39 }
40
41 inline bool spfa()
42 {
43 memset(d,0x3f,sizeof(d));
44 flag.reset();
45 int op=0,cls=1;
46 q[1]=s;
47 d[s]=0;
48 flag[s]=1;
49 while (op != cls)
50 {
51 op=op == maxn-1 ? 0 : op+1;
52 int x=q[op];
53 for (edge *p=head[x];p;p=p->next)
54 if (p->flow && d[p->to] > d[x]+p->cost)
55 {
56 d[p->to]=d[x]+p->cost;
57 prev[p->to]=p->part;
58 if (!flag[p->to])
59 {
60 if (op != cls)
61 {
62 int now=op == maxn-1 ? 0 : op+1;
63 if (d[p->to] < d[q[now]])
64 {
65 q[op]=p->to;
66 op=op == 0 ? maxn-1 : op-1;
67 }
68 else
69 {
70 cls=cls == maxn-1 ? 0 : cls+1;
71 q[cls]=p->to;
72 }
73 }
74 else
75 {
76 cls=cls == maxn-1 ? 0 : cls+1;
77 q[cls]=p->to;
78 }
79 flag[p->to]=1;
80 }
81 }
82 flag[x]=0;
83 }
84 return d[t] != inf;
85 }
86
87 inline int agument()
88 {
89 int f=inf,ans=0;
90 for (edge *p=prev[t];p;p=prev[p->to])
91 f=min(f,p->part->flow);
92 for (edge *p=prev[t];p;p=prev[p->to])
93 {
94 p->flow+=f;
95 p->part->flow-=f;
96 ans+=p->part->cost*f;
97 }
98 return ans;
99 }
100
101 inline int min_cost()
102 {
103 int ans=0;
104 while (spfa())
105 ans+=agument();
106 return ans;
107 }
108
109 int need[maxn];
110
111 int main()
112 {
113 int n,m;
114 scanf("%d%d",&n,&m);
115 for (int i=1;i<=n;i++)
116 scanf("%d",&need[i]);
117 for (int i=1;i<=m;i++)
118 {
119 int x,y,z;
120 scanf("%d%d%d",&x,&y,&z);
121 add_edge(x,y+1,inf,z);
122 }
123 need[n+1]=0;
124 for (int i=1;i<=n+1;i++)
125 {
126 int now=need[i]-need[i-1];
127 if (now >= 0)
128 add_edge(s,i,now,0);
129 else
130 add_edge(i,t,-now,0);
131 if (i > 1)
132 add_edge(i,i-1,inf,0);
133 }
134 printf("%d
",min_cost());
135 return 0;
136 }
View Code
bzoj1066
水的不能再水的网络流
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 1010
8 #define maxm 100010
9 #define s 0
10 #define t maxn-1
11 #define inf 0x3f3f3f3f
12
13 struct edge
14 {
15 int to,flow;
16 edge *part,*next;
17 }e[maxm<<1],*head[maxn];
18
19 int ne=0;
20 int q[maxn],d[maxn];
21
22 inline void add(int from,int to,int flow)
23 {
24 e[ne].to=to;
25 e[ne].flow=flow;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 inline void add_edge(int from,int to,int flow)
31 {
32 e[ne].part=&e[ne+1];
33 e[ne+1].part=&e[ne];
34 add(from,to,flow);
35 add(to,from,0);
36 }
37
38 inline bool bfs()
39 {
40 memset(d,-1,sizeof(d));
41 int op=0,cls=1;
42 q[1]=s;
43 d[s]=0;
44 while (op != cls)
45 {
46 int x=q[++op];
47 for (edge *p=head[x];p;p=p->next)
48 if (p->flow && d[p->to] == -1)
49 {
50 d[p->to]=d[x]+1;
51 q[++cls]=p->to;
52 }
53 }
54 return ~d[t];
55 }
56
57 int dfs(int now,int now_flow)
58 {
59 if (now == t)
60 return now_flow;
61 int out=now_flow;
62 for (edge *p=head[now];p;p=p->next)
63 if (p->flow && d[p->to] == d[now]+1 && out)
64 {
65 int f=dfs(p->to,min(p->flow,out));
66 p->flow-=f;
67 p->part->flow+=f;
68 out-=f;
69 }
70 if (out == now_flow)
71 d[now]=-1;
72 return now_flow-out;
73 }
74
75 inline int dinic()
76 {
77 int ans=0;
78 while (bfs())
79 ans+=dfs(s,inf);
80 return ans;
81 }
82
83 inline int sqr(int x)
84 {
85 return x*x;
86 }
87
88 int pos[50][50];
89 int map[50][50];
90
91 int main()
92 {
93 int n,m,d;
94 scanf("%d%d%d",&n,&m,&d);
95 for (int i=1;i<=n;i++)
96 for (int j=1;j<=m;j++)
97 {
98 pos[i][j]=(i-1)*m+j;
99 char ch;
100 while (ch=getchar(),ch > '9' || ch < '0');
101 map[i][j]=ch-'0';
102 if (map[i][j])
103 add_edge(pos[i][j],pos[i][j]+n*m,map[i][j]);
104 }
105 for (int i=1;i<=n;i++)
106 for (int j=1;j<=m;j++)
107 if (map[i][j])
108 {
109 for (int k=-d;k<=d;k++)
110 for (int l=-d;l<=d;l++)
111 {
112 int x=i+k,y=j+l;
113 if (x <= 0 || y <= 0 || x > n || y > m)
114 continue;
115 if (map[x][y])
116 if (sqr(i-x)+sqr(j-y) <= d*d)
117 add_edge(pos[i][j]+n*m,pos[x][y],inf);
118 }
119 if (i <= d || n-i+1 <= d || j <= d || m-j+1 <= d)
120 add_edge(pos[i][j]+n*m,t,inf);
121 }
122 int sum=0;
123 for (int i=1;i<=n;i++)
124 for (int j=1;j<=m;j++)
125 {
126 char ch;
127 while (ch=getchar(),ch != '.' && ch != 'L');
128 if (ch == 'L')
129 {
130 sum++;
131 add_edge(s,pos[i][j],1);
132 }
133 }
134 printf("%d
",sum-dinic());
135 return 0;
136 }
View Code
bzoj1067
情况比较蛋疼的st。。。还记得那年的本地AC提交RE吗?就是这道题。。。
1 #include<cstdio>
2
3 const int maxn=50010;
4
5 int f[maxn][30],bit[30],n,m;
6
7 struct rei
8 {
9 int y,v;
10 void init()
11 {
12 scanf("%d%d",&y,&v);
13 }
14 }z[maxn];
15
16 inline int max(int a,int b)
17 {
18 if (a > b)
19 return a;
20 return b;
21 }
22
23 inline int find(int y)
24 {
25 int l=0,r=n;
26 while (l+1!=r)
27 {
28 int m=(l+r)>>1;
29 if (z[m].y>=y) r=m;
30 else l=m;
31 }
32 return r;
33 }
34
35 inline int query(int l,int r)
36 {
37 if (l>r) return -1;
38 int now=0;
39 while (l+bit[now]-1<=r)
40 now++;
41 now--;
42 return max(f[l][now],f[r-bit[now]+1][now]);
43 }
44
45 int main()
46 {
47 scanf("%d",&n);
48 for (int a=1;a<=n;a++)
49 z[a].init();
50 bit[0]=1;
51 for (int a=1;a<=20;a++)
52 bit[a]=bit[a-1]*2;
53 for (int a=1;a<=n;a++)
54 f[a][0]=z[a].v;
55 for (int a=1;a<=20;a++)
56 if (bit[a]>n) break;
57 else
58 {
59 for (int b=1;b+bit[a]-1<=n;b++)
60 f[b][a]=max(f[b][a-1],f[b+bit[a-1]][a-1]);
61 }
62 scanf("%d",&m);
63 for (int a=1;a<=m;a++)
64 {
65 int x,y;
66 scanf("%d%d",&y,&x);
67 int l=find(y);
68 int r=find(x);
69 if (z[l].y==y && z[r].y==x)
70 {
71 if (z[l].v<z[r].v) printf("false
");
72 else
73 {
74 int nowv=query(l+1,r-1);
75 if (nowv>=z[r].v) printf("false
");
76 else
77 {
78 if (r-l+1==z[r].y-z[l].y+1) printf("true
");
79 else printf("maybe
");
80 }
81 }
82 }
83 else
84 {
85 if (z[l].y==y)
86 {
87 while (z[r].y>x)
88 r--;
89 int nowv=query(l+1,r);
90 if (nowv>=z[l].v) printf("false
");
91 else printf("maybe
");
92 }
93 else
94 {
95 if (z[r].y==x)
96 {
97 while (z[l].y<y)
98 l++;
99 int nowv=query(l,r-1);
100 if (nowv>=z[r].v) printf("false
");
101 else printf("maybe
");
102 }
103 else printf("maybe
");
104 }
105 }
106 }
107
108 return 0;
109 }
View Code
bzoj1070
很不错的拆点费用流,考虑每个人第几个修某辆车对总时间的贡献
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 1010
5 #define maxm 1000010
6 #define inf 0x3f3f3f3f
7
8 struct edge
9 {
10 int to,flow,cost;
11 edge *next,*part;
12 }e[maxm],*head[maxn],*prev[maxn];
13
14 int s=0,t=maxn-1;
15 int n,m,ne=0;
16 int q[maxn],d[maxn];
17 int time[10][80];
18 bool flag[maxn];
19
20 inline int min(int a,int b)
21 {
22 return a < b ? a : b;
23 }
24
25 inline void add(int from,int to,int flow,int cost)
26 {
27 e[ne].to=to;
28 e[ne].flow=flow;
29 e[ne].cost=cost;
30 e[ne].next=head[from];
31 head[from]=&e[ne++];
32 }
33
34 inline void add_edge(int from,int to,int flow,int cost)
35 {
36 e[ne].part=&e[ne+1];
37 e[ne+1].part=&e[ne];
38 add(from,to,flow,cost);
39 add(to,from,0,-cost);
40 }
41
42 inline bool spfa()
43 {
44 int op=0,cls=1;
45 memset(flag,0,sizeof(flag));
46 memset(d,0x3f,sizeof(d));
47 flag[s]=1;
48 d[s]=0;
49 q[1]=s;
50 while (op != cls)
51 {
52 op++;
53 if (op == maxn)
54 op=0;
55 int x=q[op];
56 flag[x]=0;
57 for (edge *p=head[x];p;p=p->next)
58 if (p->flow && d[x]+p->cost < d[p->to])
59 {
60 d[p->to]=d[x]+p->cost;
61 prev[p->to]=p->part;
62 if (!flag[p->to])
63 {
64 cls++;
65 if (cls == maxn)
66 cls=0;
67 q[cls]=p->to;
68 flag[p->to]=1;
69 }
70 }
71 }
72 return d[t] != inf;
73 }
74
75 inline int agument()
76 {
77 int f=inf,cost=0;
78 for (edge *p=prev[t];p;p=prev[p->to])
79 f=min(f,p->part->flow);
80 for (edge *p=prev[t];p;p=prev[p->to])
81 {
82 p->part->flow-=f;
83 p->flow+=f;
84 cost+=f*p->part->cost;
85 }
86 return cost;
87 }
88
89 inline int min_cost()
90 {
91 int out=0;
92 while (spfa())
93 out+=agument();
94 return out;
95 }
96
97 int main()
98 {
99 scanf("%d%d",&m,&n);
100 for (int i=1;i<=n;i++)
101 for (int j=1;j<=m;j++)
102 scanf("%d",&time[j][i]);
103 for (int i=1;i<=m;i++)
104 for (int j=1;j<=n;j++)
105 for (int k=1;k<=n;k++)
106 add_edge((j-1)*m+i,k+m*n,1,j*time[i][k]);
107 for (int i=1;i<=m;i++)
108 for (int j=1;j<=n;j++)
109 add_edge(s,(j-1)*m+i,1,0);
110 for (int i=1;i<=n;i++)
111 add_edge(m*n+i,t,1,0);
112 printf("%.2lf
",(double)min_cost()/n);
113 return 0;
114 }
View Code
bzoj1076
状态压缩DP求期望,倒着做
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 110
7 #define maxm 16
8
9 double f[maxn][1<<15];
10 int need[maxm];
11 double v[maxm];
12 int bit[21];
13
14 int main()
15 {
16 bit[0]=1;
17 for (int i=1;i<=20;i++)
18 bit[i]=bit[i-1]+bit[i-1];
19 int n,m;
20 scanf("%d%d",&n,&m);
21 for (int i=1;i<=m;i++)
22 {
23 scanf("%lf",&v[i]);
24 int t;
25 while (1)
26 {
27 scanf("%d",&t);
28 if (!t)
29 break;
30 need[i]|=bit[t-1];
31 }
32 }
33 for (int i=n;i;i--)
34 for (int j=0;j<bit[m];j++)
35 {
36 f[i][j]=0;
37 for (int k=1;k<=m;k++)
38 if ((j&need[k]) == need[k])
39 f[i][j]+=max(f[i+1][j],f[i+1][j|bit[k-1]]+v[k]);
40 else
41 f[i][j]+=f[i+1][j];
42 f[i][j]/=(double)m;
43 }
44 printf("%.6lf
",f[1][0]);
45 return 0;
46 }
View Code
bzoj1079
我写过的复杂度看起来最高的DP,五维的状态。。。
1 #include <cstdio>
2
3 #define maxn 16
4 #define mod 1000000007
5
6 #ifdef unix
7 #define LL "%lld"
8 #else
9 #define LL "%I64d"
10 #endif
11
12 long long now[maxn];
13 long long f[maxn][maxn][maxn][maxn][maxn][6];
14
15 long long fdp(long long a,long long b,long long c,long long d,long long e,long long last)
16 {
17 if (a+b+c+d+e == 0)
18 return 1;
19 if (f[a][b][c][d][e][last])
20 return f[a][b][c][d][e][last];
21 long long ans=0;
22 if (d > 0)
23 (ans+=(d-(last == 5))*fdp(a,b,c+1,d-1,e,4))%=mod;
24 if (c > 0)
25 (ans+=(c-(last == 4))*fdp(a,b+1,c-1,d,e,3))%=mod;
26 if (b > 0)
27 (ans+=(b-(last == 3))*fdp(a+1,b-1,c,d,e,2))%=mod;
28 if (a > 0)
29 (ans+=(a-(last == 2))*fdp(a-1,b,c,d,e,1))%=mod;
30 if (e > 0)
31 (ans+=e*fdp(a,b,c,d+1,e-1,5))%=mod;
32 return f[a][b][c][d][e][last]=ans;
33 }
34
35 int main()
36 {
37 long long n;
38 scanf(LL,&n);
39 for (long long i=1;i<=n;i++)
40 {
41 long long x;
42 scanf(LL,&x);
43 now[x]++;
44 }
45 printf(LL,fdp(now[1],now[2],now[3],now[4],now[5],0)%mod);
46 return 0;
47 }
View Code
bzoj1088
不要去想真的扫雷。。。枚举开头两个雷的状态,然后就可以递推了。。。
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 10010
5
6 int n;
7 bool f[maxn];
8 int a[maxn];
9
10 inline bool check()
11 {
12 for (int i=2;i<n;i++)
13 {
14 if (a[i] < f[i-1]+f[i])
15 return 0;
16 if (a[i] == f[i-1]+f[i])
17 f[i+1]=0;
18 if (a[i] == f[i-1]+f[i]+1)
19 f[i+1]=1;
20 if (a[i] > f[i-1]+f[i]+1)
21 return 0;
22 }
23 if (a[n] == f[n-1]+f[n])
24 return 1;
25 return 0;
26 }
27
28 int main()
29 {
30 scanf("%d",&n);
31 for (int i=1;i<=n;i++)
32 scanf("%d",&a[i]);
33 int ans=0;
34 if (a[1] == 0)
35 {
36 f[1]=f[2]=0;
37 ans+=check();
38 }
39 else
40 {
41 if (a[1] == 1)
42 {
43 f[1]=1,f[2]=0;
44 ans+=check();
45 memset(f,0,sizeof(f));
46 f[1]=0,f[2]=1;
47 ans+=check();
48 }
49 else
50 {
51 f[1]=f[2]=1;
52 ans+=check();
53 }
54 }
55 printf("%d
",ans);
56 return 0;
57 }
View Code
bzoj1089
treedp+高精
1 #include <cmath>
2 #include <string>
3 #include <cstdio>
4 #include <cstdlib>
5 #include <cstring>
6 #include <iostream>
7 #include <algorithm>
8 using namespace std;
9
10 #ifdef unix
11 #define ll "%lld"
12 #else
13 #define ll "%I64d"
14 #endif
15 class wkint {
16 private:
17 long long a[1510];
18 int len;
19 public:
20 wkint();
21 wkint(int t);
22 void read();
23 void print();
24 wkint operator + (const wkint &t) const;
25 wkint operator - (const wkint &t) const;
26 wkint operator * (const wkint &t) const;
27 wkint operator * (const int &t) const;
28 wkint operator ^ (const int &t) const;
29 wkint operator / (const int &t) const;
30 int operator % (const int &t) const;
31 bool operator < (const wkint &t) const;
32 bool operator > (const wkint &t) const;
33 bool operator == (const wkint &t) const;
34 bool operator != (const wkint &t) const;
35 };
36
37 wkint::wkint() {
38 len = 1;
39 memset(a, 0, sizeof(a));
40 }
41 wkint::wkint(int t) {
42 len = 1;
43 a[1] = t;
44 }
45 void wkint::read() {
46 string tmp;
47 cin >> tmp;
48 int lenT = tmp.length();
49 len = (lenT + 7) / 8;
50 int ptr = len, now = 0;
51 for (int i = 0; i < lenT; i ++) {
52 now *= 10; now += (int)(tmp[i] - '0');
53 if (!((lenT - i - 1) % 8)) {
54 a[ptr] = now;
55 now = 0;
56 ptr --;
57 }
58 }
59 }
60 void wkint::print() {
61 printf(ll, a[len]);
62 for (int i = len - 1; i >= 1; i --) {
63 int ws = (int)log10((long double)(a[i] + 1)) + 1;
64 for (int j = 1; j <= 8 - ws; j ++) printf("0");
65 printf(ll, a[i]);
66 }
67 printf("
");
68 }
69 wkint wkint::operator + (const wkint &t) const {
70 wkint res;
71 int maxlen = max(t.len, len);
72 for (int i = 1; i <= maxlen; i ++) {
73 res.a[i] += a[i] + t.a[i];
74 if (res.a[i] >= 100000000) {
75 res.a[i + 1] += res.a[i] / 100000000;
76 res.a[i] %= 100000000;
77 }
78 }
79 if (res.a[maxlen + 1]) maxlen ++;
80 res.len = maxlen;
81 return res;
82 }
83 wkint wkint::operator - (const wkint &t) const {
84 wkint res;
85 int maxlen = max(t.len, len);
86 for (int i = 1; i <= maxlen; i ++) {
87 res.a[i] += a[i] - t.a[i];
88 if (res.a[i] < 0) {
89 res.a[i + 1] -= 1;
90 res.a[i] += 100000000;
91 }
92 }
93 while (!res.a[maxlen]) maxlen --;
94 res.len = maxlen;
95 return res;
96 }
97 wkint wkint::operator * (const wkint &t) const {
98 wkint res;
99 int maxlen = t.len + len - 1;
100 for (int i = 1; i <= len; i ++)
101 for (int j = 1; j <= t.len; j ++) {
102 res.a[i + j - 1] += a[i] * t.a[j];
103 }
104 for (int i = 1; i <= maxlen; i ++)
105 if (res.a[i] > 100000000) {
106 res.a[i + 1] += res.a[i] / 100000000;
107 res.a[i] %= 100000000;
108 }
109 if (res.a[maxlen + 1]) maxlen ++;
110 res.len = maxlen;
111 return res;
112 }
113 wkint wkint::operator * (const int &t) const {
114 wkint res;
115 res.len = len;
116 for (int i = 1; i <= len; i ++) {
117 res.a[i] += a[i] * t;
118 if (res.a[i] > 100000000) {
119 res.a[i + 1] += res.a[i] / 100000000;
120 res.a[i] %= 100000000;
121 }
122 }
123 if (res.a[res.len + 1]) res.len ++;
124 return res;
125 }
126 wkint wkint::operator ^ (const int &t) const {
127 wkint res = wkint(1), tmp;
128 int now = t;
129 memcpy(tmp.a, a, sizeof(a));
130 tmp.len = len;
131 while (now) {
132 if (now & 1) res = res * tmp;
133 tmp = tmp * tmp;
134 now >>= 1;
135 }
136 return res;
137 }
138 wkint wkint::operator / (const int &t) const {
139 wkint res;
140 long long now = 0;
141 res.len = len;
142 for (int i = len; i >= 1; i --) {
143 now *= 100000000, now += a[i];
144 if (now < t) {
145 res.a[i] = 0;
146 } else {
147 res.a[i] = now / t;
148 now %= t;
149 }
150 }
151 while (!res.a[res.len]) res.len --;
152 return res;
153 }
154 int wkint::operator % (const int &t) const {
155 long long now = 0;
156 for (int i = len; i >= 1; i --) {
157 now *= 100000000, now += a[i];
158 now %= t;
159 }
160 return (int)now;
161 }
162 bool wkint::operator < (const wkint &t) const {
163 if (len < t.len) return true;
164 if (len > t.len) return false;
165 for (int i = len; i >= 1; i --)
166 if (a[i] < t.a[i]) {
167 return true;
168 } else if (a[i] > t.a[i]) {
169 return false;
170 }
171 return false;
172 }
173 bool wkint::operator > (const wkint &t) const {
174 if (len > t.len) return true;
175 if (len < t.len) return false;
176 for (int i = len; i >= 1; i --)
177 if (a[i] > t.a[i]) {
178 return true;
179 } else if (a[i] < t.a[i]) {
180 return false;
181 }
182 return false;
183 }
184 bool wkint::operator == (const wkint &t) const {
185 if (t.len != len) return false;
186 for (int i = 1; i <= len; i ++)
187 if (a[i] != t.a[i]) {
188 return false;
189 }
190 return true;
191 }
192 bool wkint::operator != (const wkint &t) const {
193 if (t.len != len) return true;
194 for (int i = 1; i <= len; i ++)
195 if (a[i] != t.a[i]) {
196 return true;
197 }
198 return false;
199 }
200
201 wkint f[40];
202
203 wkint pow(wkint a,int b)
204 {
205 wkint ans=1;
206 for (;b;b>>=1)
207 {
208 if (b&1)
209 ans=ans*a;
210 a=a*a;
211 }
212 return ans;
213 }
214
215 int main()
216 {
217 int n,d;
218 scanf("%d%d",&n,&d);
219 if (d < 2)
220 {
221 puts("1");
222 return 0;
223 }
224 f[0]=1;
225 f[1]=2;
226 for (int i=2;i<=d;i++)
227 f[i]=pow(f[i-1],n)+1;
228 f[d]=f[d]-f[d-1];
229 f[d].print();
230 return 0;
231 }
View Code
bzoj1093
tarjan缩点然后DFS(虽然很多人认为那是DP。。。)
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 100010
8 #define maxm 1000010
9
10 struct edge
11 {
12 int to;
13 edge *next;
14 }e[maxm],*head[maxn];
15
16 int time=0;
17 int ne=0;
18 int p;
19 int cnt=0;
20 int from[maxm],to[maxm],pos[maxm],flag[maxm];
21 int size[maxn];
22 int dfn[maxn],low[maxn],sta[maxn],belong[maxn],top=0;
23 bool vis[maxn];
24 int f[maxn],q[maxn],g[maxn],in[maxn];
25
26 inline void inc(int &a,int b)
27 {
28 a+=b;
29 while (a >= p)
30 a-=p;
31 }
32
33 inline void read(int &x)
34 {
35 char ch;
36 while (ch=getchar(),ch > '9' || ch < '0');
37 x=ch-'0';
38 while (ch=getchar(),ch <= '9' && ch >= '0')
39 x=(x<<3)+x+x+ch-'0';
40 }
41
42 inline void add_edge(int from,int to)
43 {
44 e[ne].to=to;
45 e[ne].next=head[from];
46 head[from]=&e[ne++];
47 }
48
49 inline void tarjan(int now)
50 {
51 dfn[now]=low[now]=++time;
52 sta[++top]=now;
53 vis[now]=1;
54 for (edge *p=head[now];p;p=p->next)
55 if (!dfn[p->to])
56 {
57 tarjan(p->to);
58 low[now]=min(low[now],low[p->to]);
59 }
60 else
61 if (vis[p->to])
62 low[now]=min(low[now],dfn[p->to]);
63 if (dfn[now] == low[now])
64 {
65 int p;
66 cnt++;
67 do
68 {
69 p=sta[top--];
70 vis[p]=0;
71 belong[p]=cnt;
72 size[cnt]++;
73 }
74 while (p != now);
75 }
76 }
77
78 inline void dfs(int now)
79 {
80 if (f[now])
81 return;
82 int _max=0;
83 for (edge *p=head[now];p;p=p->next)
84 {
85 dfs(p->to);
86 f[now]=max(f[now],f[p->to]+size[now]);
87 }
88 if (!f[now])
89 {
90 f[now]=size[now];
91 g[now]=1;
92 }
93 for (edge *p=head[now];p;p=p->next)
94 if (f[p->to]+size[now] == f[now])
95 inc(g[now],g[p->to]);
96 }
97
98 inline bool cmp(const int a,const int b)
99 {
100 return (belong[from[a]] < belong[from[b]]) || (belong[from[a]] == belong[from[b]] && belong[to[a]] < belong[to[b]]);
101 }
102
103 int main()
104 {
105 int n,m;
106 read(n);
107 read(m);
108 read(p);
109 for (int i=1;i<=m;i++)
110 {
111 read(from[i]);
112 read(to[i]);
113 add_edge(from[i],to[i]);
114 pos[i]=i;
115 flag[i]=1;
116 }
117 for (int i=1;i<=n;i++)
118 if (!dfn[i])
119 tarjan(i);
120 memset(head,0,sizeof(head));
121 memset(vis,0,sizeof(vis));
122 ne=0;
123 sort(pos+1,pos+m+1,cmp);
124 for (int i=1;i<=m;i++)
125 {
126 int x=pos[i];
127 if (belong[from[x]] == belong[to[x]])
128 flag[x]=0;
129 else
130 if (belong[from[x]] == belong[from[pos[i-1]]] && belong[to[x]] == belong[to[pos[i-1]]])
131 flag[x]=0;
132 }
133 for (int i=1;i<=m;i++)
134 if (flag[i])
135 {
136 add_edge(belong[from[i]],belong[to[i]]);
137 in[belong[to[i]]]++;
138 }
139 for (int i=1;i<=cnt;i++)
140 if (!in[i])
141 dfs(i);
142 int _max=0;
143 for (int i=1;i<=cnt;i++)
144 _max=max(_max,f[i]);
145 printf("%d
",_max);
146 int ans=0;
147 for (int i=1;i<=cnt;i++)
148 if (f[i] == _max)
149 inc(ans,g[i]);
150 printf("%d
",ans);
151 return 0;
152 }
View Code
bzoj1096
斜率优化的DP
1 #include <cstdio>
2
3 #define maxn 1000010
4
5 #ifdef unix
6 #define LL "%lld"
7 #else
8 #define LL "%I64d"
9 #endif
10
11 long long dp[maxn],sum[maxn],a[maxn],c[maxn],l[maxn];
12 long long q[maxn];
13
14 inline void read(long long &x)
15 {
16 char ch;
17 while (ch=getchar(),ch > '9' || ch < '0');
18 x=ch-'0';
19 while (ch=getchar(),ch <= '9' && ch >= '0')
20 x=(x<<3)+x+x+ch-'0';
21 }
22
23 inline long long calc(long long x,long long y)
24 {
25 return dp[x]-dp[y]+a[x]-a[y];
26 }
27
28 int main()
29 {
30 long long n;
31 read(n);
32 for (long long i=1;i<=n;i++)
33 {
34 read(l[i]);
35 read(sum[i]);
36 read(c[i]);
37 a[i]=l[i]*sum[i];
38 a[i]+=a[i-1];
39 sum[i]+=sum[i-1];
40 }
41 long long op=0,cls=0;
42 for (long long i=1;i<=n;i++)
43 {
44 while (op != cls && calc(q[op+1],q[op]) <= l[i]*(sum[q[op+1]]-sum[q[op]]))
45 op++;
46 dp[i]=dp[q[op]]+(sum[i]-sum[q[op]])*l[i]-(a[i]-a[q[op]])+c[i];
47 while (op != cls && calc(i,q[cls])*(sum[q[cls]]-sum[q[cls-1]]) < calc(q[cls],q[cls-1])*(sum[i]-sum[q[cls]]))
48 cls--;
49 q[++cls]=i;
50 }
51 printf(LL,dp[n]);
52 return 0;
53 }
View Code
bzoj1103
DFS序上建立树状数组
1 #include <cstdio>
2
3 #define maxn 250010
4
5 struct edge
6 {
7 int to;
8 edge *next;
9 }e[maxn],*head[maxn];
10
11 int ne=0;
12
13 inline void read(int &x)
14 {
15 x=0;
16 char ch;
17 while (ch=getchar(),ch > '9' || ch < '0');
18 x=ch-'0';
19 while (ch=getchar(),ch <= '9' && ch >= '0')
20 x=(x<<3)+x+x+ch-'0';
21 }
22
23 inline void add_edge(int from,int to)
24 {
25 e[ne].to=to;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 int n;
31 int l[maxn],r[maxn],bit[maxn];
32
33 void dfs(int now)
34 {
35 l[now]=++ne;
36 for (edge *p=head[now];p;p=p->next)
37 dfs(p->to);
38 r[now]=ne;
39 }
40
41 inline void bit_update(int now,int add)
42 {
43 for (;now<=n;now+=now&-now)
44 bit[now]+=add;
45 }
46
47 inline int query(int now)
48 {
49 int ans=0;
50 for (;now;now-=now&-now)
51 ans+=bit[now];
52 return ans;
53 }
54
55 int main()
56 {
57 read(n);
58 for (int i=1;i<n;i++)
59 {
60 int x,y;
61 read(x);
62 read(y);
63 if (x > y)
64 x^=y^=x^=y;
65 add_edge(x,y);
66 }
67 ne=0;
68 dfs(1);
69 for (int i=1;i<=n;i++)
70 bit[i]=i&-i;
71 for (int i=1;i<=n;i++)
72 bit_update(r[i]+1,-1);
73 int m;
74 read(m);
75 for (int i=1;i<=n+m-1;i++)
76 {
77 char s[2];
78 scanf("%s",s);
79 if (s[0] == 'W')
80 {
81 int x;
82 read(x);
83 printf("%d
",query(l[x])-1);
84 }
85 else
86 {
87 int x,y;
88 read(x);
89 read(y);
90 if (x < y)
91 x^=y^=x^=y;
92 bit_update(l[x],-1);
93 bit_update(r[x]+1,1);
94 }
95 }
96 return 0;
97 }
View Code
bzoj1143
处理出每个点能到达的所有点,然后拆点二分图最大独立集
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 510
8 #define maxm 1000010
9 #define inf 0x3f3f3f3f
10 #define s 0
11 #define t maxn-1
12
13 struct edge
14 {
15 int to,flow;
16 edge *next,*part;
17 }e[maxm],*head[maxn];
18
19 int ne=0;
20 int q[maxn],d[maxn];
21 bool map[maxn][maxn];
22 bool flag[maxn];
23
24 inline void add(int from,int to,int flow)
25 {
26 e[ne].to=to;
27 e[ne].flow=flow;
28 e[ne].next=head[from];
29 head[from]=&e[ne++];
30 }
31
32 inline void add_edge(int from,int to,int flow)
33 {
34 e[ne].part=&e[ne+1];
35 e[ne+1].part=&e[ne];
36 add(from,to,flow);
37 add(to,from,0);
38 }
39
40 inline void add_edge(int from,int to)
41 {
42 e[ne].to=to;
43 e[ne].next=head[from];
44 head[from]=&e[ne++];
45 }
46
47 inline bool bfs()
48 {
49 int op=0,cls=1;
50 memset(d,-1,sizeof(d));
51 q[1]=s;
52 d[s]=0;
53 while (op != cls)
54 {
55 int x=q[++op];
56 for (edge *p=head[x];p;p=p->next)
57 if (p->flow && d[p->to] == -1)
58 {
59 q[++cls]=p->to;
60 d[p->to]=d[x]+1;
61 }
62 }
63 return ~d[t];
64 }
65
66 int dfs(int now,int now_flow)
67 {
68 if (now == t)
69 return now_flow;
70 int out=now_flow;
71 for (edge *p=head[now];p;p=p->next)
72 if (p->flow && d[p->to] == d[now]+1 && out)
73 {
74 int f=dfs(p->to,min(p->flow,out));
75 p->flow-=f;
76 p->part->flow+=f;
77 out-=f;
78 }
79 if (out == now_flow)
80 d[now]=-1;
81 return now_flow-out;
82 }
83
84 inline int dinic()
85 {
86 int ans=0;
87 while (bfs())
88 ans+=dfs(s,inf);
89 return ans;
90 }
91
92 inline void bfs(int now)
93 {
94 memset(flag,0,sizeof(flag));
95 int op=0,cls=1;
96 q[1]=now;
97 flag[now]=1;
98 while (op != cls)
99 {
100 int x=q[++op];
101 for (edge *p=head[x];p;p=p->next)
102 if (!flag[p->to])
103 {
104 q[++cls]=p->to;
105 map[now][p->to]=1;
106 flag[p->to]=1;
107 }
108 }
109 }
110
111 int main()
112 {
113 int n,m;
114 scanf("%d%d",&n,&m);
115 for (int i=1;i<=m;i++)
116 {
117 int x,y;
118 scanf("%d%d",&x,&y);
119 add_edge(x,y);
120 }
121 for (int i=1;i<=n;i++)
122 bfs(i);
123 memset(head,0,sizeof(head));
124 ne=0;
125 for (int i=1;i<=n;i++)
126 for (int j=1;j<=n;j++)
127 if (map[i][j])
128 add_edge(i,j+n,1);
129 for (int i=1;i<=n;i++)
130 {
131 add_edge(s,i,1);
132 add_edge(i+n,t,1);
133 }
134 printf("%d
",n-dinic());
135 return 0;
136 }
View Code
bzoj1146
当年的做法是树链剖分树套树,现在可以在DFS序上建立树状数组套主席树来解决,orz rank1的大刷子crf
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 80010
8
9 struct Node
10 {
11 int size;
12 Node* s[2];
13 }t[maxn*160],*root[maxn],null,*L[100],*R[100];
14
15 struct edge
16 {
17 int to;
18 edge *next;
19 }e[maxn<<1],*head[maxn];
20
21 struct query
22 {
23 int to,num;
24 query *next;
25 }que[maxn<<1],*begin[maxn];
26
27 int n,m,size,ne=0,lsize,rsize;
28 int a[maxn],b[maxn<<1],q[maxn][3],lca[maxn];
29 int l[maxn],r[maxn];
30 int anc[maxn],f[maxn],fa[maxn],rank[maxn];
31 bool flag[maxn];
32
33 inline void add_edge(int from,int to)
34 {
35 e[ne].to=to;
36 e[ne].next=head[from];
37 head[from]=&e[ne++];
38 }
39
40 inline void add_query(int from,int to,int num)
41 {
42 que[ne].to=to;
43 que[ne].num=num;
44 que[ne].next=begin[from];
45 begin[from]=&que[ne++];
46 }
47
48 inline void read(int &x)
49 {
50 char ch;
51 while (ch=getchar(),ch > 57 || ch < 48);
52 x=ch-48;
53 while (ch=getchar(),ch <= 57 && ch >= 48)
54 x=(x<<3)+x+x+ch-48;
55 }
56
57 int find(int now)
58 {
59 if (f[now] == now)
60 return now;
61 return f[now]=find(f[now]);
62 }
63
64 inline void _union(int x,int y)
65 {
66 int a=find(x);
67 int b=find(y);
68 if (a == b)
69 return;
70 if (rank[a] <= rank[b])
71 {
72 f[a]=b;
73 rank[b]+=rank[a];
74 }
75 else
76 {
77 f[b]=a;
78 rank[a]+=rank[b];
79 }
80 }
81
82 void dfs(int now)
83 {
84 f[now]=now;
85 anc[now]=now;
86 flag[now]=1;
87 l[now]=++ne;
88 for (edge *p=head[now];p;p=p->next)
89 if (!flag[p->to])
90 {
91 dfs(p->to);
92 fa[p->to]=now;
93 _union(now,p->to);
94 anc[find(now)]=now;
95 }
96 for (query *q=begin[now];q;q=q->next)
97 if (flag[q->to])
98 lca[q->num]=anc[find(q->to)];
99 r[now]=ne;
100 }
101
102 inline void update(Node* now,int val,int flag)
103 {
104 int l=1,r=size;
105 while (1)
106 {
107 now->size+=flag;
108 if (l == r)
109 return;
110 int mid=(l+r)>>1;
111 if (val <= mid)
112 {
113 if (now->s[0] == &null)
114 {
115 now->s[0]=&t[ne++];
116 now->s[0]->s[0]=now->s[0]->s[1]=&null;
117 now->s[0]->size=0;
118 }
119 now=now->s[0];
120 r=mid;
121 }
122 else
123 {
124 if (now->s[1] == &null)
125 {
126 now->s[1]=&t[ne++];
127 now->s[1]->s[0]=now->s[1]->s[1]=&null;
128 now->s[1]->size=0;
129 }
130 now=now->s[1];
131 l=mid+1;
132 }
133 }
134 }
135
136 inline void bit_update(int now,int val,int flag)
137 {
138 for (;now<=n;now+=now&-now)
139 update(root[now],val,flag);
140 }
141
142 inline int query(int x,int y,int lca,int flca,int k)
143 {
144 lsize=rsize=0;
145 x=l[x];
146 y=l[y];
147 lca=l[lca];
148 flca=l[flca];
149 int del=0;
150 for (;x>0;x-=x&-x)
151 {
152 R[++rsize]=root[x];
153 del+=R[rsize]->size;
154 }
155 for (;y>0;y-=y&-y)
156 {
157 R[++rsize]=root[y];
158 del+=R[rsize]->size;
159 }
160 for (;lca>0;lca-=lca&-lca)
161 {
162 L[++lsize]=root[lca];
163 del-=L[lsize]->size;
164 }
165 for (;flca>0;flca-=flca&-flca)
166 {
167 L[++lsize]=root[flca];
168 del-=L[lsize]->size;
169 }
170 if (del < k)
171 return -1;
172 int l=1,r=size;
173 while (1)
174 {
175 if (l == r)
176 return l;
177 int mid=(l+r)>>1;
178 del=0;
179 for (int i=1;i<=rsize;i++)
180 del+=R[i]->s[1]->size;
181 for (int i=1;i<=lsize;i++)
182 del-=L[i]->s[1]->size;
183 if (k <= del)
184 {
185 for (int i=1;i<=lsize;i++)
186 L[i]=L[i]->s[1];
187 for (int i=1;i<=rsize;i++)
188 R[i]=R[i]->s[1];
189 l=mid+1;
190 }
191 else
192 {
193 for (int i=1;i<=lsize;i++)
194 L[i]=L[i]->s[0];
195 for (int i=1;i<=rsize;i++)
196 R[i]=R[i]->s[0];
197 k-=del;
198 r=mid;
199 }
200 }
201 }
202
203 int main()
204 {
205 // freopen("1.in","r",stdin);
206 // freopen("1.out","w",stdout);
207 read(n);
208 read(m);
209 for (int i=1;i<=n;i++)
210 {
211 read(a[i]);
212 b[i]=a[i];
213 }
214 size=n;
215 for (int i=1;i<n;i++)
216 {
217 int x,y;
218 read(x);
219 read(y);
220 add_edge(x,y);
221 add_edge(y,x);
222 }
223 ne=0;
224 for (int i=1;i<=m;i++)
225 {
226 read(q[i][0]);
227 read(q[i][1]);
228 read(q[i][2]);
229 if (!q[i][0])
230 b[++size]=q[i][2];
231 else
232 {
233 add_query(q[i][1],q[i][2],i);
234 add_query(q[i][2],q[i][1],i);
235 }
236 }
237 ne=0;
238 sort(b+1,b+size+1);
239 size=unique(b+1,b+size+1)-b-1;
240 for (int i=1;i<=n;i++)
241 a[i]=lower_bound(b+1,b+size+1,a[i])-b;
242 null.s[0]=null.s[1]=&null;
243 null.size=0;
244 dfs(1);
245 ne=0;
246 for (int i=0;i<=n;i++)
247 {
248 root[i]=&t[ne++];
249 root[i]->s[0]=root[i]->s[1]=&null;
250 root[i]->size=0;
251 }
252 for (int i=1;i<=n;i++)
253 {
254 bit_update(l[i],a[i],1);
255 bit_update(r[i]+1,a[i],-1);
256 }
257 for (int i=1;i<=m;i++)
258 {
259 if (!q[i][0])
260 {
261 bit_update(l[q[i][1]],a[q[i][1]],-1);
262 bit_update(r[q[i][1]]+1,a[q[i][1]],1);
263 a[q[i][1]]=lower_bound(b+1,b+size+1,q[i][2])-b;
264 bit_update(l[q[i][1]],a[q[i][1]],1);
265 bit_update(r[q[i][1]]+1,a[q[i][1]],-1);
266 }
267 else
268 {
269 int ans=query(q[i][1],q[i][2],lca[i],fa[lca[i]],q[i][0]);
270 if (ans != -1)
271 printf("%d
",b[ans]);
272 else
273 printf("invalid request!
");
274 }
275 }
276 return 0;
277 }
View Code
bzoj1179
tarjan缩点后做最长路
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 500010
8 #define maxm 1000010
9
10 struct edge
11 {
12 int to,dist;
13 edge *next;
14 }e[maxm],*head[maxn];
15
16 int s,t;
17 int cnt=0;
18 int ne=0,time=0;
19 int from[maxm],to[maxm];
20 int dfn[maxn],low[maxn],belong[maxn],sta[maxn],top=0;
21 int d[maxn],v[maxn],f[maxn],q[maxn];
22 bool vis[maxn];
23
24 inline void add_edge(int from,int to)
25 {
26 e[ne].to=to;
27 e[ne].next=head[from];
28 head[from]=&e[ne++];
29 }
30
31 inline void tarjan(int now)
32 {
33 dfn[now]=low[now]=++time;
34 sta[++top]=now;
35 vis[now]=1;
36 for (edge *p=head[now];p;p=p->next)
37 if (!dfn[p->to])
38 {
39 tarjan(p->to);
40 low[now]=min(low[now],low[p->to]);
41 }
42 else
43 if (vis[p->to])
44 low[now]=min(low[now],dfn[p->to]);
45 if (dfn[now] == low[now])
46 {
47 int p;
48 cnt++;
49 do
50 {
51 p=sta[top--];
52 vis[p]=0;
53 belong[p]=cnt;
54 f[cnt]+=v[p];
55 }
56 while (p != now);
57 }
58 }
59
60 inline int spfa()
61 {
62 memset(vis,0,sizeof(vis));
63 int op=0,cls=1;
64 q[1]=s;
65 d[s]=f[s];
66 vis[s]=1;
67 while (op != cls)
68 {
69 op=op == maxn-1 ? 0 : op+1;
70 int x=q[op];
71 for (edge *p=head[x];p;p=p->next)
72 if (d[p->to] < d[x]+f[p->to])
73 {
74 d[p->to]=d[x]+f[p->to];
75 if (!vis[p->to])
76 {
77 vis[p->to]=1;
78 if (op != cls)
79 {
80 int now=op == maxn-1 ? 0 : op+1;
81 if (d[p->to] > d[q[now]])
82 {
83 q[op]=p->to;
84 op=op ? op-1 : maxn-1;
85 }
86 else
87 {
88 cls=cls == maxn-1 ? 0 : cls+1;
89 q[cls]=p->to;
90 }
91 }
92 else
93 {
94 cls=cls == maxn-1 ? 0 : cls+1;
95 q[cls]=p->to;
96 }
97 }
98 }
99 vis[x]=0;
100 }
101 return d[t];
102 }
103
104 inline void read(int &x)
105 {
106 x=0;
107 char ch;
108 while (ch=getchar(),ch > '9' || ch < '0');
109 x=ch-'0';
110 while (ch=getchar(),ch <= '9' && ch >= '0')
111 x=(x<<3)+x+x+ch-'0';
112 }
113
114 int main()
115 {
116 int n,m;
117 read(n);
118 read(m);
119 for (int i=1;i<=m;i++)
120 {
121 read(from[i]);
122 read(to[i]);
123 add_edge(from[i],to[i]);
124 belong[i]=i;
125 }
126 for (int i=1;i<=n;i++)
127 read(v[i]);
128 for (int i=1;i<=n;i++)
129 if (!dfn[i])
130 tarjan(i);
131 read(s);
132 s=belong[s];
133 t=cnt+1;
134 memset(head,0,sizeof(head));
135 ne=0;
136 for (int i=1;i<=m;i++)
137 if (belong[from[i]] != belong[to[i]])
138 add_edge(belong[from[i]],belong[to[i]]);
139 int p;
140 read(p);
141 for (int i=1;i<=p;i++)
142 {
143 int x;
144 read(x);
145 add_edge(belong[x],t);
146 }
147 printf("%d
",spfa());
148 return 0;
149 }
View Code
bzoj1191
正解是匈牙利,我看了一眼数据范围,加上又不会写匈牙利,然后就写了奇慢无比的枚举加边网络流
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 2010
5 #define maxm 100010
6 #define inf 0x3f3f3f3f
7
8 struct edge
9 {
10 int to,flow;
11 edge *part,*next;
12 }e[maxm],*head[maxn];
13
14 int s=0,t=maxn-1,ne=0;
15 int q[maxn],d[maxn];
16
17 inline int min(int a,int b)
18 {
19 return a < b ? a : b;
20 }
21
22 inline void add(int from,int to,int flow)
23 {
24 e[ne].to=to;
25 e[ne].flow=flow;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 inline void add_edge(int from,int to,int flow)
31 {
32 e[ne].part=&e[ne+1];
33 e[ne+1].part=&e[ne];
34 add(from,to,flow);
35 add(to,from,0);
36 }
37
38 inline bool bfs()
39 {
40 memset(d,-1,sizeof(d));
41 int op=0,cls=1;
42 q[1]=s;
43 d[s]=0;
44 while (op != cls)
45 {
46 int x=q[++op];
47 for (edge *p=head[x];p;p=p->next)
48 if (p->flow && d[p->to] == -1)
49 {
50 d[p->to]=d[x]+1;
51 q[++cls]=p->to;
52 }
53 }
54 return d[t] != -1;
55 }
56
57 int dfs(int now,int now_flow)
58 {
59 if (now == t)
60 return now_flow;
61 int out=now_flow;
62 for (edge *p=head[now];p;p=p->next)
63 if (p->flow && d[p->to] == d[now]+1 && out)
64 {
65 int f=dfs(p->to,min(p->flow,out));
66 p->flow-=f;
67 p->part->flow+=f;
68 out-=f;
69 }
70 if (out == now_flow)
71 d[now]=-1;
72 return now_flow-out;
73 }
74
75 inline int dinic()
76 {
77 int ans=0;
78 while (bfs())
79 ans+=dfs(s,inf);
80 return ans;
81 }
82
83 int main()
84 {
85 int n,m;
86 scanf("%d%d",&n,&m);
87 for (int i=1;i<=m;i++)
88 {
89 int x,y;
90 scanf("%d%d",&x,&y);
91 x++;
92 y++;
93 add_edge(x,i+n,1);
94 if (x != y)
95 add_edge(y,i+n,1);
96 }
97 for (int i=1;i<=n;i++)
98 add_edge(s,i,1);
99 int ans=0;
100 for (int i=n+1;i<=n+m;i++)
101 {
102 add_edge(i,t,1);
103 int now=dinic();
104 if (now)
105 ans++;
106 else
107 break;
108 }
109 printf("%d
",ans);
110 return 0;
111 }
View Code
bzoj1192
可以竞选bzoj十大水题了。。。不会具体证明,举了几个例子发现没问题之后就写了,然后就A了
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 long long bit[50];
7
8 int main()
9 {
10 long long x;
11 bit[0]=1;
12 for (int i=1;i<=40;i++)
13 bit[i]=bit[i-1]+bit[i-1];
14 scanf("%lld",&x);
15 printf("%d
",upper_bound(bit,bit+40,x)-bit);
16 return 0;
17 }
View Code
bzoj1196
本来是需要二分最长一级公路的长度的,不知道为什么直接MST也是对的。。。应该是数据太水
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 10010
7 #define maxm 20010
8
9 struct edge
10 {
11 int from,to,d1,d2,flag;
12 }e[maxm];
13
14 int f[maxn],r[maxn];
15
16 inline bool cmp1(const edge a,const edge b)
17 {
18 return a.d1 < b.d1;
19 }
20
21 inline bool cmp2(const edge a,const edge b)
22 {
23 return a.d2 < b.d2;
24 }
25
26 int find(int x)
27 {
28 if (f[x] == x)
29 return x;
30 return f[x]=find(f[x]);
31 }
32
33 inline void _union(int x,int y)
34 {
35 if (r[x] <= r[y])
36 {
37 f[x]=y;
38 r[y]+=r[x];
39 }
40 else
41 {
42 f[y]=x;
43 r[x]+=r[y];
44 }
45 }
46
47 int main()
48 {
49 int n,k,m;
50 scanf("%d%d%d",&n,&k,&m);
51 for (int i=1;i<m;i++)
52 scanf("%d%d%d%d",&e[i].from,&e[i].to,&e[i].d1,&e[i].d2);
53 for (int i=1;i<=n;i++)
54 {
55 f[i]=i;
56 r[i]=1;
57 }
58 int cnt=0,ans=0;
59 if (k)
60 {
61 sort(e+1,e+m,cmp1);
62 for (int i=1;i<=m;i++)
63 {
64 int x=find(e[i].from),y=find(e[i].to);
65 if (x == y)
66 continue;
67 _union(x,y);
68 k--;
69 cnt++;
70 e[i].flag=1;
71 ans=max(ans,e[i].d1);
72 if (!k)
73 break;
74 }
75 }
76 sort(e+1,e+m,cmp2);
77 for (int i=1;i<=m;i++)
78 if (!e[i].flag)
79 {
80 int x=find(e[i].from),y=find(e[i].to);
81 if (x == y)
82 continue;
83 _union(x,y);
84 cnt++;
85 ans=max(ans,e[i].d2);
86 if (cnt == n-1)
87 break;
88 }
89 printf("%d
",ans);
90 return 0;
91 }
View Code
bzoj1207
m^2的DP
1 #include <cstdio>
2
3 #define maxn 10010
4
5 int f[maxn];
6 int x[maxn],y[maxn],t[maxn];
7
8 inline void read(int &x)
9 {
10 char ch;
11 while (ch=getchar(),ch > '9' || ch < '0');
12 x=ch-'0';
13 while (ch=getchar(),ch <= '9' && ch >= '0')
14 x=(x<<3)+x+x+ch-'0';
15 }
16
17 inline int abs(int x)
18 {
19 return x >= 0 ? x : -x;
20 }
21
22 inline int max(int a,int b)
23 {
24 return a > b ? a : b;
25 }
26
27 int main()
28 {
29 int n,m;
30 read(n);
31 read(m);
32 for (int i=1;i<=m;i++)
33 {
34 read(t[i]);
35 read(x[i]);
36 read(y[i]);
37 }
38 for (int i=2;i<=m;i++)
39 for (int j=1;j<i;j++)
40 if (abs(y[i]-y[j])+abs(x[i]-x[j]) <= t[i]-t[j])
41 f[i]=max(f[i],f[j]+1);
42 int ans=0;
43 for (int i=1;i<=m;i++)
44 ans=max(ans,f[i]);
45 printf("%d
",ans+1);
46 return 0;
47 }
View Code
bzoj1208
裸的平衡树
1 #include <cstdio>
2
3 const int maxn=80010;
4 const int mod=1000000;
5 const int inf=0x3f3f3f3f;
6
7 int n,flag=-1,ans=0;
8
9 struct Node
10 {
11 int v,size;
12 Node* s[2];
13 Node()
14 {
15 v=size=0;
16 }
17 };
18
19 struct sbt
20 {
21 Node t[maxn],null;
22 Node *root;
23 int ne;
24
25 sbt()
26 {
27 ne=0;
28 null.s[0]=null.s[1]=&null;
29 root=&null;
30 }
31
32 inline void _rot(Node* &now,int l)
33 {
34 int r=!l;
35 Node* s=now->s[l];
36 now->s[l]=s->s[r];
37 s->s[r]=now;
38 s->size=now->size;
39 now->size=now->s[0]->size+now->s[1]->size+1;
40 now=s;
41 }
42
43 void _maintain(Node* &now,int l)
44 {
45 int r=!l;
46 if (now->s[l]->s[l]->size > now->s[r]->size)
47 _rot(now,l);
48 else
49 {
50 if (now->s[l]->s[r]->size > now->s[r]->size)
51 {
52 _rot(now->s[l],r);
53 _rot(now,l);
54 }
55 else
56 return;
57 }
58 _maintain(now->s[0],0);
59 _maintain(now->s[1],1);
60 _maintain(now,0);
61 _maintain(now,1);
62 }
63
64 void insert(Node* &now,int v)
65 {
66 if (now == &null)
67 {
68 now=&t[ne++];
69 now->v=v;
70 now->size=1;
71 now->s[0]=now->s[1]=&null;
72 return;
73 }
74 now->size++;
75 if (v < now->v)
76 insert(now->s[0],v);
77 else
78 insert(now->s[1],v);
79 _maintain(now,v >= now->v);
80 }
81
82 inline int pred(int v)
83 {
84 Node* now=root;
85 int ans=-inf;
86 while (1)
87 {
88 if (now == &null)
89 return ans;
90 if (v <= now->v)
91 now=now->s[0];
92 else
93 {
94 ans=now->v;
95 now=now->s[1];
96 }
97 }
98 }
99
100 inline int suc(int v)
101 {
102 Node* now=root;
103 int ans=inf;
104 while (1)
105 {
106 if (now == &null)
107 return ans;
108 if (v >= now->v)
109 now=now->s[1];
110 else
111 {
112 ans=now->v;
113 now=now->s[0];
114 }
115 }
116 }
117
118 inline bool find(int v)
119 {
120 Node* now=root;
121 while (1)
122 {
123 if (now == &null)
124 return 0;
125 if (now->v == v)
126 return 1;
127 now=now->s[v >= now->v];
128 }
129 }
130
131 int del(Node* &now,int v)
132 {
133 now->size--;
134 if (now->v == v || (v < now->v && now->s[0] == &null) || (v > now->v && now->s[1] == &null))
135 {
136 int t=now->v;
137 if (now->s[0] == &null)
138 now=now->s[1];
139 else
140 {
141 if (now->s[1] == &null)
142 now=now->s[0];
143 else
144 now->v=del(now->s[1],0);
145 }
146 return t;
147 }
148 else
149 {
150 if (v < now->v)
151 del(now->s[0],v);
152 else
153 del(now->s[1],v);
154 }
155 }
156 }t;
157
158 int main()
159 {
160 scanf("%d",&n);
161 int x,y;
162 for (int i=1;i<=n;i++)
163 {
164 scanf("%d%d",&x,&y);
165 if (flag == -1)
166 {
167 flag=x;
168 t.insert(t.root,y);
169 }
170 else
171 {
172 if (flag == x)
173 t.insert(t.root,y);
174 else
175 {
176 int l,r;
177 if (t.find(y))
178 t.del(t.root,y);
179 else
180 {
181 l=t.pred(y);
182 r=t.suc(y);
183 if (y-l <= r-y)
184 {
185 ans+=y-l;
186 ans%=mod;
187 t.del(t.root,l);
188 }
189 else
190 {
191 ans+=r-y;
192 ans%=mod;
193 t.del(t.root,r);
194 }
195 }
196 if (t.root->size == 0)
197 flag=-1;
198 }
199 }
200 }
201 printf("%d
",ans);
202 return 0;
203 }
View Code
bzoj1211
prufer编码,不用高精
1 #include <cstdio>
2
3 #define maxn 160
4
5 long long d[maxn];
6
7 int main()
8 {
9 long long n;
10 scanf("%lld",&n);
11 long long ans=1,sum=0;
12 for (long long i=1;i<=n;i++)
13 {
14 scanf("%lld",&d[i]);
15 if (d[i] >= n)
16 {
17 puts("0");
18 return 0;
19 }
20 d[i]--;
21 sum+=d[i];
22 }
23 if (sum != n-2)
24 {
25 puts("0");
26 return 0;
27 }
28 for (long long i=1;i<=n-2;i++)
29 {
30 ans*=n-2-i+1;
31 for (long long j=1;j<=n;j++)
32 if (d[j] >= i)
33 ans/=i;
34 }
35 printf("%lld
",ans);
36 return 0;
37 }
View Code
bzoj1221
很不错的费用流建模练手题
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 10010
8 #define maxm 1000010
9 #define inf 0x3f3f3f3f
10 #define s 0
11 #define t maxn-1
12
13 struct edge
14 {
15 int to,flow,cost;
16 edge *next,*part;
17 }e[maxm],*head[maxn],*prev[maxn];
18
19 int ne=0;
20 int q[maxn],d[maxn];
21 bool flag[maxn];
22
23 inline void add(int from,int to,int flow,int cost)
24 {
25 e[ne].to=to;
26 e[ne].flow=flow;
27 e[ne].cost=cost;
28 e[ne].next=head[from];
29 head[from]=&e[ne++];
30 }
31
32 inline void add_edge(int from,int to,int flow,int cost)
33 {
34 e[ne].part=&e[ne+1];
35 e[ne+1].part=&e[ne];
36 add(from,to,flow,cost);
37 add(to,from,0,-cost);
38 }
39
40 inline bool spfa()
41 {
42 memset(d,0x3f,sizeof(d));
43 memset(flag,0,sizeof(flag));
44 int op=0,cls=1;
45 q[1]=s;
46 d[s]=0;
47 flag[s]=1;
48 while (op != cls)
49 {
50 op=op == maxn-1 ? 0 : op+1;
51 int x=q[op];
52 for (edge *p=head[x];p;p=p->next)
53 if (p->flow && d[p->to] > d[x]+p->cost)
54 {
55 d[p->to]=d[x]+p->cost;
56 prev[p->to]=p->part;
57 if (!flag[p->to])
58 {
59 if (op != cls)
60 {
61 int now=op == maxn-1 ? 0 : op+1;
62 if (d[p->to] < d[q[now]])
63 {
64 q[op]=p->to;
65 op=op == 0 ? maxn-1 : op-1;
66 }
67 else
68 {
69 cls=cls == maxn-1 ? 0 : cls+1;
70 q[cls]=p->to;
71 }
72 }
73 else
74 {
75 cls=cls == maxn-1 ? 0 : cls+1;
76 q[cls]=p->to;
77 }
78 flag[p->to]=1;
79 }
80 }
81 flag[x]=0;
82 }
83 return d[t] != inf;
84 }
85
86 inline int agument()
87 {
88 int f=inf,ans=0;
89 for (edge *p=prev[t];p;p=prev[p->to])
90 f=min(f,p->part->flow);
91 for (edge *p=prev[t];p;p=prev[p->to])
92 {
93 p->flow+=f;
94 p->part->flow-=f;
95 ans+=p->part->cost*f;
96 }
97 return ans;
98 }
99
100 inline int min_cost()
101 {
102 int ans=0;
103 while (spfa())
104 ans+=agument();
105 return ans;
106 }
107
108 int main()
109 {
110 int n,a,b,f,fa,fb;
111 scanf("%d%d%d%d%d%d",&n,&a,&b,&f,&fa,&fb);
112 for (int i=1;i<=n;i++)
113 {
114 int x;
115 scanf("%d",&x);
116 add_edge(s,i,inf,f);
117 add_edge(i,t,x,0);
118 add_edge(s,i+n,x,0);
119 if (i+a+1 <= n)
120 add_edge(i+n,i+a+1,inf,fa);
121 if (i+b+1 <= n)
122 add_edge(i+n,i+b+1,inf,fb);
123 if (i < n)
124 add_edge(i+n,i+n+1,inf,0);
125 }
126 printf("%d
",min_cost());
127 return 0;
128 }
View Code
bzoj1230(已隐藏)
水线段树
1 #include <cstdio>
2
3 #define maxn 100010
4
5 struct Node
6 {
7 int sum,lazy;
8 }t[maxn<<2];
9
10 inline void update(int rt)
11 {
12 t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;
13 }
14
15 inline void pushdown(int l,int r,int rt)
16 {
17 if (!t[rt].lazy)
18 return;
19 int mid=(l+r)>>1;
20 t[rt<<1].lazy^=1;
21 t[rt<<1|1].lazy^=1;
22 t[rt<<1].sum=mid-l+1-t[rt<<1].sum;
23 t[rt<<1|1].sum=r-mid-t[rt<<1|1].sum;
24 t[rt].lazy=0;
25 }
26
27 void insert(int l,int r,int rt,int L,int R)
28 {
29 if (l >= L && r <= R)
30 {
31 t[rt].sum=r-l+1-t[rt].sum;
32 t[rt].lazy^=1;
33 return;
34 }
35 int mid=(l+r)>>1;
36 pushdown(l,r,rt);
37 if (L <= mid)
38 insert(l,mid,rt<<1,L,R);
39 if (R > mid)
40 insert(mid+1,r,rt<<1|1,L,R);
41 update(rt);
42 }
43
44 int query(int l,int r,int rt,int L,int R)
45 {
46 if (l >= L && r <= R)
47 return t[rt].sum;
48 int mid=(l+r)>>1,ans=0;
49 pushdown(l,r,rt);
50 if (L <= mid)
51 ans+=query(l,mid,rt<<1,L,R);
52 if (R > mid)
53 ans+=query(mid+1,r,rt<<1|1,L,R);
54 update(rt);
55 return ans;
56 }
57
58 inline void read(int &x)
59 {
60 char ch;
61 while (ch=getchar(),ch > '9' || ch < '0');
62 x=ch-'0';
63 while (ch=getchar(),ch <= '9' && ch >= '0')
64 x=(x<<3)+x+x+ch-'0';
65 }
66
67 int main()
68 {
69 int n,m;
70 read(n);
71 read(m);
72 while (m--)
73 {
74 int x,y,z;
75 read(x);
76 read(y);
77 read(z);
78 if (!x)
79 insert(1,n,1,y,z);
80 else
81 printf("%d
",query(1,n,1,y,z));
82 }
83 return 0;
84 }
View Code
bzoj1237
a[i]只会与b[i] b[i-1] b[i-2]配对,证明不会。。。
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 100010
8 #define inf 0x3f3f3f3f3f3f3f3fLL
9
10 long long a[maxn],b[maxn];
11
12 inline void read(long long &x)
13 {
14 char ch;
15 while (ch=getchar(),ch > '9' || ch < '0');
16 x=ch-'0';
17 while (ch=getchar(),ch <= '9' && ch >= '0')
18 x=(x<<3)+x+x+ch-'0';
19 }
20
21 inline long long cal(long long x,long long y)
22 {
23 if (a[x] == b[y])
24 return inf;
25 return abs(a[x]-b[y]);
26 }
27
28 long long f[maxn];
29
30 int main()
31 {
32 long long n;
33 read(n);
34 for (long long i=1;i<=n;i++)
35 {
36 read(a[i]);
37 read(b[i]);
38 }
39 sort(a+1,a+n+1);
40 sort(b+1,b+n+1);
41 memset(f,0x3f,sizeof(f));
42 f[0]=0;
43 f[1]=cal(1,1);
44 f[2]=min(f[1]+cal(2,2),cal(1,2)+cal(2,1));
45 for (long long i=3;i<=n;i++)
46 f[i]=min(min(min(min(f[i],f[i-1]+cal(i,i)),f[i-2]+cal(i,i-1)+cal(i-1,i)),f[i-3]+cal(i-2,i-1)+cal(i-1,i)+cal(i,i-2)),f[i-3]+cal(i-2,i)+cal(i-1,i-2)+cal(i,i-1));
47 printf("%lld
",f[n]);
48 return 0;
49 }
View Code
bzoj1251
终结他一脸啊。。。那么水的splay
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 500010
7 #define inf 0x3f3f3f3f
8
9 struct Node
10 {
11 int v,max,size,add;
12 bool rot;
13 Node *s[2],*par;
14
15 Node()
16 {
17 v=max=size=add=rot=0;
18 }
19
20 inline bool S()
21 {
22 return this == par->s[1];
23 }
24 };
25
26 struct splay
27 {
28 Node t[maxn],null;
29 Node *root;
30 int ne;
31
32 splay()
33 {
34 null.s[0]=null.s[1]=null.par=&null;
35 null.max=null.v=-inf;
36 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2;
37 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1;
38 ne=2;
39 root=&t[0];
40 }
41
42 inline void add(Node* now,int d)
43 {
44 now->max+=d;
45 now->v+=d;
46 now->add+=d;
47 }
48
49 inline void _update(Node* now)
50 {
51 if (now == &null)
52 return;
53 now->size=now->s[0]->size+now->s[1]->size+1;
54 now->max=max(max(now->s[0]->max,now->s[1]->max),now->v);
55 }
56
57 inline void _pushdown(Node* now)
58 {
59 if (now == &null)
60 return;
61 if (now->rot)
62 {
63 swap(now->s[0],now->s[1]);
64 now->s[0]->rot^=1;
65 now->s[1]->rot^=1;
66 now->rot=0;
67 }
68 if (now->add)
69 {
70 int d=now->add;
71 add(now->s[0],d);
72 add(now->s[1],d);
73 now->add=0;
74 null.v=null.max=-inf;
75 }
76 }
77
78 inline void build(int n)
79 {
80 Node* now=root;
81 now->size+=n;
82 now=now->s[1];
83 now->size+=n;
84 Node* par=now;
85 for (int i=1;i<=n;i++)
86 {
87 now=&t[ne++];
88 (par->s[0]=now)->par=par;
89 now->s[0]=now->s[1]=&null;
90 now->size=n-i+1;
91 par=now;
92 }
93 }
94
95 inline void _rot(Node* now,int l)
96 {
97 int r=!l;
98 Node* s=now->s[l];
99 Node* p=now->par;
100 (now->s[l]=s->s[r])->par=now;
101 (s->s[r]=now)->par=s;
102 s->par=p;
103 if (p != &null)
104 p->s[now == p->s[1]]=s;
105 _update(now);
106 _update(s);
107 }
108
109 void relax(Node* now)
110 {
111 if (now->par != &null)
112 relax(now->par);
113 _pushdown(now);
114 }
115
116 inline void _splay(Node* now,Node* goal)
117 {
118 relax(now);
119 while (now->par != goal)
120 {
121 Node* p=now->par;
122 Node* g=p->par;
123 bool dp=now == p->s[1];
124 bool dg=p == g->s[1];
125 if (p->par == goal)
126 {
127 _rot(p,dp);
128 break;
129 }
130 if (dp == dg)
131 {
132 _rot(g,dg);
133 _rot(p,dp);
134 }
135 else
136 {
137 _rot(p,dp);
138 _rot(g,dg);
139 }
140 }
141 if (goal == &null)
142 root=now;
143 }
144
145 inline Node* _select(int v)
146 {
147 Node* now=root;
148 while (1)
149 {
150 _pushdown(now);
151 if (now == &null)
152 return now;
153 if (now->s[0]->size+1 == v)
154 return now;
155 if (v <= now->s[0]->size)
156 now=now->s[0];
157 else
158 {
159 v-=now->s[0]->size+1;
160 now=now->s[1];
161 }
162 }
163 }
164
165 inline void change(int l,int r,int d)
166 {
167 Node* p=_select(l);
168 Node* q=_select(r+2);
169 _splay(p,&null);
170 _splay(q,root);
171 add(q->s[0],d);
172 _update(q);
173 _update(p);
174 }
175
176 inline void rot(int l,int r)
177 {
178 Node* p=_select(l);
179 Node* q=_select(r+2);
180 _splay(p,&null);
181 _splay(q,root);
182 q->s[0]->rot^=1;
183 }
184
185 inline int query(int l,int r)
186 {
187 Node* p=_select(l);
188 Node* q=_select(r+2);
189 _splay(p,&null);
190 _splay(q,root);
191 return q->s[0]->max;
192 }
193
194 void travel(Node* now)
195 {
196 if (now->s[0] != &null)
197 travel(now->s[0]);
198 printf("%d %d %d %d %d
",now->v,now->max,now->size,now->rot,now->add);
199 if (now->s[1] != &null)
200 travel(now->s[1]);
201 }
202 }t;
203
204 int main()
205 {
206 int n,m;
207 scanf("%d%d",&n,&m);
208 t.build(n);
209 while (m--)
210 {
211 int x,y,z,w;
212 scanf("%d%d%d",&x,&y,&z);
213 if (x == 1)
214 {
215 scanf("%d",&w);
216 t.change(y,z,w);
217 }
218 if (x == 2)
219 t.rot(y,z);
220 if (x == 3)
221 printf("%d
",t.query(y,z));
222 }
223 return 0;
224 }
View Code
bzoj1257
前sqrt(n)裸,后面的按照商分类
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 long long n,k;
7
8 int main()
9 {
10 scanf("%lld%lld",&n,&k);
11 long long ans=0;
12 for (long long i=1;i<=n;i++)
13 {
14 long long a=k/i,l=k/(a+1)+1,r=a?k/a:n;
15 if (r >= n)
16 r=n;
17 ans+=k*(r-l+1)-a*(l+r)*(r-l+1)/2;
18 i=r;
19 }
20 printf("%lld
",ans);
21 return 0;
22 }
View Code
bzoj1263
直观感受是尽量化成3,然后用2补齐,然后加上高精即可
1 #include <iostream>
2 #include <cstdio>
3 #include <algorithm>
4 #include <cstring>
5 using namespace std;
6 struct wkint
7 {
8 int z[10000],l;
9 bool zf;
10 int maxl(int a,int b)
11 {
12 if (a>b) return(a);
13 else return(b);
14 }
15 bool operator==(const wkint &a)
16 {
17 if (zf ^ a.zf) return(false);
18 if (l!=a.l) return(false);
19 int b;
20 for (b=l;b>=1;b--)
21 if (z[b]!=a.z[b]) return(false);
22 return(true);
23 }
24 bool operator>(const wkint &a)
25 {
26 if (zf ^ a.zf)
27 {
28 if (zf==true) return(true);
29 else return(false);
30 }
31 if (l>a.l) return(zf);
32 if (l<a.l) return(!zf);
33 int b;
34 for (b=l;b>=1;b--)
35 if (z[b]!=a.z[b])
36 {
37 if (z[b]>a.z[b]) return(zf);
38 else return(!zf);
39 }
40 return(false);
41 }
42 bool operator>=(const wkint &a)
43 {
44 wkint b;
45 b=0;
46 for (int c=0;c<=l;c++)
47 b.z[c]=z[c];
48 b.l=l;
49 b.zf=zf;
50 if ((b>a) || (b==a)) return(true);
51 else return(false);
52 }
53 bool operator<(const wkint &a)
54 {
55 wkint b;
56 b=0;
57 for (int c=0;c<=l;c++)
58 b.z[c]=z[c];
59 b.l=l;
60 b.zf=zf;
61 return(!(b>=a));
62 }
63 bool operator<=(const wkint &a)
64 {
65 wkint b;
66 b=0;
67 for (int c=0;c<=l;c++)
68 b.z[c]=z[c];
69 b.l=l;
70 b.zf=zf;
71 return(!(b>a));
72 }
73 bool operator!=(const wkint &a)
74 {
75 wkint b;
76 b=0;
77 for (int c=0;c<=l;c++)
78 b.z[c]=z[c];
79 b.l=l;
80 b.zf=zf;
81 return(!(b==a));
82 }
83 int operator=(const int &a)
84 {
85 memset(z,0,sizeof(z));
86 l=0;
87 int b=a;
88 if (b<0)
89 {
90 zf=false;
91 b=-b;
92 }
93 else zf=true;
94 do
95 {
96 l++;
97 z[l]=b % 10;
98 b=b / 10;
99 }while(b!=0);
100 return(0);
101 }
102 wkint operator+(const wkint &a)
103 {
104 wkint ans;
105 memset(ans.z,0,sizeof(ans.z));
106 if (zf ^ a.zf)
107 {
108 int b;
109 wkint c;
110 c.zf=zf;
111 for (b=0;b<=l;b++)
112 c.z[b]=z[b];
113 c.l=l;
114 if (zf==true)
115 {
116 wkint d;
117 for (b=0;b<=a.l;b++)
118 d.z[b]=a.z[b];
119 d.l=a.l;
120 d.zf=true;
121 ans=c-d;
122 return(ans);
123 }
124 else
125 {
126 c.zf=true;
127 wkint d=a;
128 ans=d-c;
129 return(ans);
130 }
131 }
132 int ll=maxl(l,a.l);
133 ans.l=ll;
134 int b;
135 for (b=1;b<=ll;b++)
136 {
137 ans.z[b]=ans.z[b]+z[b]+a.z[b];
138 ans.z[b+1]=ans.z[b] / 10;
139 ans.z[b]=ans.z[b] % 10;
140 }
141 for (ans.l=ll+2;ans.l>=1;ans.l--)
142 if (ans.z[ans.l]!=0) break;
143 ans.zf=zf;
144 return(ans);
145 }
146 wkint operator-(const wkint &a)
147 {
148 wkint ans;
149 memset(ans.z,0,sizeof(0));
150 if (zf ^ a.zf)
151 {
152 int b;
153 wkint c;
154 for (b=1;b<=l;b++)
155 c.z[b]=z[b];
156 c.l=l;
157 c.zf=zf;
158 if (zf==true)
159 {
160 wkint d;
161 for (b=1;b<=a.l;b++)
162 d.z[b]=a.z[b];
163 d.l=a.l;
164 d.zf=true;
165 ans=c+d;
166 return(ans);
167 }
168 else
169 {
170 c.zf=true;
171 ans=c+a;
172 ans.zf=false;
173 return(ans);
174 }
175 }
176 int b;
177 wkint c;
178 for (b=1;b<=l;b++)
179 c.z[b]=z[b];
180 c.l=l;
181 c.zf=zf;
182 wkint e=a;
183 if (c>=a) ans.zf=true;
184 else
185 {
186 wkint d;
187 d=e;
188 e=c;
189 c=d;
190 ans.zf=false;
191 }
192 int ll=maxl(c.l,e.l);
193 for (b=1;b<=ll;b++)
194 ans.z[b]=c.z[b]-e.z[b];
195 for (b=1;b<=ll;b++)
196 if (ans.z[b]<0)
197 {
198 ans.z[b]=ans.z[b]+10;
199 ans.z[b+1]--;
200 }
201 for (b=ll;b>=1;b--)
202 if (ans.z[b]!=0) break;
203 if (b==0) b=1;
204 ans.l=b;
205 return(ans);
206 }
207 wkint operator*(const wkint &a)
208 {
209 wkint ans;
210 memset(ans.z,0,sizeof(ans.z));
211 ans.zf=!(zf ^ a.zf);
212 int b,c;
213 for (b=1;b<=l;b++)
214 for (c=1;c<=a.l;c++)
215 ans.z[b+c-1]=ans.z[b+c-1]+z[b]*a.z[c];
216 c=0;
217 for (b=1;b<=l+a.l;b++)
218 {
219 ans.z[b]=ans.z[b]+c;
220 c=ans.z[b] / 10;
221 ans.z[b]=ans.z[b] % 10;
222 }
223 while (c!=0)
224 {
225 b++;
226 ans.z[b]=c % 10;
227 c=c /10;
228 }
229 for (c=b;c>=1;c--)
230 if (ans.z[c]!=0) break;
231 if (c==0) c=1;
232 ans.l=c;
233 return(ans);
234 }
235 int print()
236 {
237 int a;
238 if (zf==false) printf("-");
239 for (a=l;a>=max(1,l-99);a--)
240 printf("%d",z[a]);
241 printf("
");
242 return(0);
243 }
244 int printl()
245 {
246 if (zf==true) printf("%d
",l);
247 else printf("%d
",l+1);
248 return(0);
249 }
250 }now;
251
252 int main()
253 {
254 int n;
255 wkint ans;
256 ans=1;
257 scanf("%d",&n);
258 if (n%3 == 1)
259 {
260 ans=4;
261 n-=4;
262 }
263 if (n%3 == 2)
264 {
265 ans=2;
266 n-=2;
267 }
268 n/=3;
269 wkint wk;
270 wk=3;
271 for (;n;n>>=1)
272 {
273 if (n&1)
274 ans=ans*wk;
275 wk=wk*wk;
276 }
277 ans.printl();
278 ans.print();
279 return 0;
280 }
View Code
bzoj1266
最短路图上的最小割
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 510
8 #define maxm 500010
9 #define inf 0x3f3f3f3f
10
11 struct edge
12 {
13 int to,flow;
14 edge *next,*part;
15 }e[maxm],*head[maxn];
16
17 int ne=0;
18 int s,t;
19 int q[maxn],d[maxn];
20 int from[maxm],to[maxm],dist[maxm],flow[maxm];
21 bool flag[maxn];
22
23 inline void add_edge0(int from,int to,int flow)
24 {
25 e[ne].to=to;
26 e[ne].flow=flow;
27 e[ne].next=head[from];
28 head[from]=&e[ne++];
29 }
30
31 inline void add(int from,int to,int flow)
32 {
33 e[ne].to=to;
34 e[ne].flow=flow;
35 e[ne].next=head[from];
36 head[from]=&e[ne++];
37 }
38
39 inline void add_edge(int from,int to,int flow)
40 {
41 e[ne].part=&e[ne+1];
42 e[ne+1].part=&e[ne];
43 add(from,to,flow);
44 add(to,from,0);
45 }
46
47 inline void spfa()
48 {
49 memset(d,0x3f,sizeof(d));
50 memset(flag,0,sizeof(flag));
51 int op=0,cls=1;
52 q[1]=s;
53 d[s]=0;
54 flag[s]=1;
55 while (op != cls)
56 {
57 op=op == maxn-1 ? 0 : op+1;
58 int x=q[op];
59 for (edge *p=head[x];p;p=p->next)
60 if (d[x]+p->flow < d[p->to])
61 {
62 d[p->to]=d[x]+p->flow;
63 if (!flag[p->to])
64 {
65 flag[p->to]=1;
66 if (op != cls)
67 {
68 int now=op == maxn-1 ? 0 : op+1;
69 if (d[p->to] < d[q[now]])
70 {
71 q[op]=p->to;
72 op=op ? op-1 : maxn-1;
73 }
74 else
75 {
76 cls=cls == maxn-1 ? 0 : cls+1;
77 q[cls]=p->to;
78 }
79 }
80 else
81 {
82 cls=cls == maxn-1 ? 0 : cls+1;
83 q[cls]=p->to;
84 }
85 }
86 }
87 flag[x]=0;
88 }
89 }
90
91 inline bool bfs()
92 {
93 memset(d,-1,sizeof(d));
94 int op=0,cls=1;
95 q[1]=s;
96 d[s]=0;
97 while (op != cls)
98 {
99 int x=q[++op];
100 for (edge *p=head[x];p;p=p->next)
101 if (p->flow && d[p->to] == -1)
102 {
103 d[p->to]=d[x]+1;
104 q[++cls]=p->to;
105 }
106 }
107 return ~d[t];
108 }
109
110 inline int dfs(int now,int now_flow)
111 {
112 if (now == t)
113 return now_flow;
114 int out=now_flow;
115 for (edge *p=head[now];p;p=p->next)
116 if (p->flow && d[p->to] == d[now]+1 && out)
117 {
118 int f=dfs(p->to,min(p->flow,out));
119 p->flow-=f;
120 p->part->flow+=f;
121 out-=f;
122 }
123 if (out == now_flow)
124 d[now]=-1;
125 return now_flow-out;
126 }
127
128 inline int dinic()
129 {
130 int ans=0;
131 while (bfs())
132 ans+=dfs(s,inf);
133 return ans;
134 }
135
136 int main()
137 {
138 int n,m;
139 scanf("%d%d",&n,&m);
140 s=1;
141 t=n;
142 for (int i=1;i<=m;i++)
143 {
144 scanf("%d%d%d%d",&from[i],&to[i],&dist[i],&flow[i]);
145 add_edge0(from[i],to[i],dist[i]);
146 add_edge0(to[i],from[i],dist[i]);
147 }
148 spfa();
149 printf("%d
",d[t]);
150 memset(head,0,sizeof(head));
151 ne=0;
152 for (int i=1;i<=m;i++)
153 {
154 if (d[from[i]]+dist[i] == d[to[i]])
155 add_edge(from[i],to[i],flow[i]);
156 if (d[to[i]]+dist[i] == d[from[i]])
157 add_edge(to[i],from[i],flow[i]);
158 }
159 printf("%d
",dinic());
160 return 0;
161 }
View Code
bzoj1269
人生中第一道splay。。。注意使用保护节点(这句话是说给不会splay的同学的)
1 #include <cstdio>
2
3 const int maxn=1024*1024*3;
4
5 int n;
6 char s[maxn],st[10];
7
8 struct Node
9 {
10 int size;
11 bool rot;
12 char ch;
13 Node *par,*s[2];
14 Node()
15 {
16 size=0;
17 rot=false;
18 }
19 };
20
21 struct splay
22 {
23 Node t[maxn],null;
24 Node* root;
25 int size;
26 splay()
27 {
28 root=&t[1];
29 size=2;
30 null.par=null.s[0]=null.s[1]=&null;
31 t[1].s[0]=&null;t[1].s[1]=&t[2];t[1].par=&null;t[1].size=2;
32 t[2].s[0]=&null;t[2].s[1]=&null;t[2].par=&t[1];t[2].size=1;
33 }
34
35 void _update(Node* now)
36 {
37 now->size=now->s[0]->size+now->s[1]->size+1;
38 }
39
40 void _pushdown(Node* now)
41 {
42 if (now != &null && now->rot)
43 {
44 now->s[0]->rot^=1;
45 now->s[1]->rot^=1;
46 Node* temp=now->s[0]->s[0];
47 now->s[0]->s[0]=now->s[0]->s[1];
48 now->s[0]->s[1]=temp;
49 temp=now->s[1]->s[0];
50 now->s[1]->s[0]=now->s[1]->s[1];
51 now->s[1]->s[1]=temp;
52 now->rot=false;
53 }
54 }
55
56 void _rot(Node* now,int l)
57 {
58 int r=!l;
59 Node* s=now->s[l];
60 Node* p=now->par;
61 (now->s[l]=s->s[r])->par=now;
62 (s->s[r]=now)->par=s;
63 s->par=p;
64 if (p != &null)
65 p->s[now == p->s[1]]=s;
66 _update(now);
67 _update(s);
68 }
69
70 void _splay(Node* now,Node* goal)
71 {
72 while (now->par != goal)
73 {
74 Node* p=now->par;
75 Node* g=p->par;
76 _pushdown(g);
77 _pushdown(p);
78 bool dp=now == p->s[1];
79 bool dg=p == g->s[1];
80 if (g == goal)
81 {
82 _rot(p,dp);
83 }
84 else
85 {
86 if (dp == dg)
87 {
88 _rot(g,dg);
89 _rot(p,dp);
90 }
91 else
92 {
93 _rot(p,dp);
94 _rot(g,dg);
95 }
96 }
97 }
98 if (goal == &null)
99 root=now;
100 }
101
102 Node* _select(int v)
103 {
104 Node* now=root;
105 while (v)
106 {
107 _pushdown(now);
108 if (now->s[0]->size+1 == v)
109 return now;
110 else
111 {
112 if (v <= now->s[0]->size)
113 now=now->s[0];
114 else
115 {
116 v-=now->s[0]->size+1;
117 now=now->s[1];
118 }
119 }
120 }
121 return &null;
122 }
123
124 void insert(int pos,int len)
125 {
126 Node* p=_select(pos);
127 Node* q=_select(pos+1);
128 _splay(p,&null);
129 _splay(q,root);
130 Node* now=root;
131 now->size+=len;
132 now=now->s[1];
133 now->size+=len;
134 Node* par=now;
135 for (int i=1;i<=len;i++)
136 {
137 scanf("%c",&s[i]);
138 if (s[i] == '
' || s[i] == '
')
139 i--;
140 }
141 for (int i=1;i<=len;i++)
142 {
143 size++;
144 now=&t[size];
145 (par->s[0]=now)->par=par;
146 now->s[0]=now->s[1]=&null;
147 now->size=len-i+1;
148 now->ch=s[len-i+1];
149 par=now;
150 }
151 _splay(now,&null);
152 }
153
154 void del(int pos,int len)
155 {
156 Node* p=_select(pos);
157 Node* q=_select(pos+len+1);
158 _splay(p,&null);
159 _splay(q,root);
160 root->s[1]->s[0]=&null;
161 _update(root->s[1]);
162 _update(root);
163 }
164
165 void rot(int pos,int len)
166 {
167 Node* p=_select(pos);
168 Node* q=_select(pos+len+1);
169 _splay(p,&null);
170 _splay(q,root);
171 Node* now=root->s[1]->s[0];
172 now->rot^=1;
173 Node* temp=now->s[0];
174 now->s[0]=now->s[1];
175 now->s[1]=temp;
176 }
177
178 void print(int pos)
179 {
180 Node* now=_select(pos);
181 _splay(now,&null);
182 printf("%c",now->ch);
183 printf("
");
184 }
185 }t;
186
187 int main()
188 {
189 int pos=1,len;
190 scanf("%d",&n);
191 while (n--)
192 {
193 scanf("%s",st);
194 if (st[0] == 'M')
195 {
196 scanf("%d",&pos);
197 pos++;
198 }
199 if (st[0] == 'I')
200 {
201 scanf("%d",&len);
202 char c='~';
203 while (c != '
' && c != '
')
204 c=getchar();
205 t.insert(pos,len);
206 }
207 if (st[0] == 'D')
208 {
209 scanf("%d",&len);
210 t.del(pos,len);
211 }
212 if (st[0] == 'R')
213 {
214 scanf("%d",&len);
215 t.rot(pos,len);
216 }
217 if (st[0] == 'G')
218 {
219 t.print(pos+1);
220 }
221 if (st[0] == 'P')
222 pos--;
223 if (st[0] == 'N')
224 pos++;
225 }
226 return 0;
227 }
View Code
bzoj1272
组合数求模终极版的弱化版+一点点容斥,必须要预处理阶乘才能过(相比之下2142是多么的良心。。。以近乎裸的方式过了)详细做法可以百度组合数求模看AC大神的日志
1 #include <cstdio>
2
3 int n,t,m,p;
4 int a[20],mul[100010],ans=0;
5 bool use[20];
6
7 inline void inc(int &a,int b)
8 {
9 a+=b;
10 while (a >= p)
11 a-=p;
12 }
13
14 inline void dec(int &a,int b)
15 {
16 a-=b;
17 while (a < 0)
18 a+=p;
19 }
20
21 inline int pow(int a,int b)
22 {
23 int ans=1;
24 while (b)
25 {
26 if (b&1)
27 ans=(long long)ans*a%p;
28 a=(long long)a*a%p;
29 b>>=1;
30 }
31 return ans;
32 }
33
34 inline int get(int v)
35 {
36 int ans=0;
37 while (v)
38 {
39 ans+=v/p;
40 v/=p;
41 }
42 return ans;
43 }
44
45 inline int cal(int n)
46 {
47 if (n < p)
48 return mul[n];
49 else
50 return (long long)pow(mul[p],n/p)*cal(n/p)%p*mul[n%p]%p;
51 }
52
53 inline int calc(int a,int b)
54 {
55 int now=get(a)-get(b)-get(a-b);
56 if (now)
57 return 0;
58 return (long long)cal(a)*pow(cal(b),p-2)%p*pow(cal(a-b),p-2)%p;
59 }
60
61 inline void solve()
62 {
63 int now=m,ban=0;
64 for (int i=1;i<=t;i++)
65 if (use[i])
66 {
67 ban++;
68 now-=a[i]+1;
69 }
70 if (now < 0)
71 return;
72 if (ban%2 == 0)
73 inc(ans,calc(now+n,n));
74 else
75 dec(ans,calc(now+n,n));
76 }
77
78 inline void dfs(int now)
79 {
80 if (now > t)
81 solve();
82 else
83 {
84 use[now]=0;
85 dfs(now+1);
86 use[now]=1;
87 dfs(now+1);
88 }
89 }
90
91 int main()
92 {
93 scanf("%d%d%d%d",&n,&t,&m,&p);
94 for (int i=1;i<=t;i++)
95 scanf("%d",&a[i]);
96 mul[0]=1;
97 for (int i=1;i<p;i++)
98 mul[i]=(long long)mul[i-1]*i%p;
99 mul[p]=mul[p-1];
100 dfs(1);
101 printf("%d
",ans);
102 }
View Code
bzoj1273
在序列只有整体加上一个数的情况下,对于每一个2^i,答案存在循环节,于是暴力预处理之后O(1)回答询问即可
1 #include <cstdio>
2
3 #define maxn 100010
4
5 int a[16][maxn],ans[16][maxn];
6 int bit[20];
7
8 inline void read(int &x)
9 {
10 char ch;
11 while (ch=getchar(),ch > '9' || ch < '0');
12 x=ch-'0';
13 while (ch=getchar(),ch <= '9' && ch >= '0')
14 x=(x<<3)+x+x+ch-'0';
15 }
16
17 int main()
18 {
19 int n,_;
20 read(n);
21 read(_);
22 bit[0]=1;
23 for (int i=1;i<=18;i++)
24 bit[i]=bit[i-1]+bit[i-1];
25 for (int i=1;i<=n;i++)
26 {
27 int x;
28 read(x);
29 for (int j=0;j<16;j++)
30 a[j][x%bit[j+1]]++;
31 }
32 for (int i=0;i<16;i++)
33 for (int j=bit[i];j<bit[i+1];j++)
34 ans[i][0]+=a[i][j];
35 for (int i=0;i<16;i++)
36 for (int j=1;j<bit[i+1];j++)
37 {
38 ans[i][j]=ans[i][j-1];
39 ans[i][j]+=a[i][(bit[i]-j+bit[i+1])%bit[i+1]];
40 ans[i][j]-=a[i][bit[i+1]-j];
41 }
42 int add=0;
43 long long now=0;
44 while (_--)
45 {
46 char s[2];
47 int x;
48 scanf("%s",s);
49 read(x);
50 if (s[0] == 'A')
51 (add+=x)%=65536;
52 else
53 if (x < 16)
54 now+=ans[x][add%bit[x+1]];
55 }
56 printf("%lld
",now);
57 return 0;
58 }
View Code
bzoj1296
水水的DP,当时想各种优化状态,结果人弱写挂没办法。。。然后就暴力DP了
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 55
7 #define maxt 2510
8
9 int f[maxn][maxn][maxt][2];
10 bool map[maxn][maxn];
11
12 int main()
13 {
14 int n,m,t;
15 scanf("%d%d%d",&n,&m,&t);
16 for (int i=1;i<=n;i++)
17 for (int j=1;j<=m;j++)
18 {
19 char ch;
20 while (ch=getchar(),ch != '1' && ch != '0');
21 map[i][j]=ch-'0';
22 }
23 for (int i=1;i<=n;i++)
24 {
25 bool now=map[i][1];
26 for (int j=min((i-1)*m+1,t);j;j--)
27 {
28 f[i][1][j][now]=max(f[i-1][m][j-1][0],f[i-1][m][j-1][1])+1;
29 f[i][1][j][!now]=f[i][1][j][now]-1;
30 }
31 for (int j=2;j<=m;j++)
32 {
33 now=map[i][j];
34 for (int k=min((i-1)*m+j,t);k;k--)
35 {
36 f[i][j][k][now]=max(f[i][j-1][k][now]+1,f[i][j-1][k-1][!now]+1);
37 f[i][j][k][!now]=f[i][j-1][k][!now];
38 }
39 }
40 }
41 int ans=0;
42 for (int i=1;i<=t;i++)
43 ans=max(max(f[n][m][i][0],f[n][m][i][1]),ans);
44 printf("%d
",ans);
45 return 0;
46 }
View Code
bzoj1303
把所有比b大的赋为1,比b小的赋为-1,找到b所在的位置,然后向两边拓展,处理出前(后)缀和为x的个数,最后合并。。。怀念pascal可以负数下标
1 #include <cstdio>
2
3 #define maxn 100010
4 #define inf 0x3f3f3f3f
5
6 int a[maxn],sum[maxn<<1];
7
8 inline void read(int &x)
9 {
10 char ch;
11 while (ch=getchar(),ch > '9' || ch < '0');
12 x=ch-'0';
13 while (ch=getchar(),ch <= '9' && ch >= '0')
14 x=(x<<3)+x+x+ch-'0';
15 }
16
17 int main()
18 {
19 int n,b;
20 read(n);
21 read(b);
22 int now=0;
23 for (int i=1;i<=n;i++)
24 {
25 int x;
26 scanf("%d",&x);
27 if (x < b)
28 a[i]=-1;
29 else
30 if (x > b)
31 a[i]=1;
32 else
33 {
34 now=i;
35 a[i]=0;
36 }
37 }
38 sum[n]++;
39 for (int i=now+1;i<=n;i++)
40 {
41 a[i]+=a[i-1];
42 sum[a[i]+n]++;
43 }
44 int ans=0,num=0;
45 for (int i=now;i;i--)
46 {
47 num+=a[i];
48 ans+=sum[-num+n];
49 }
50 printf("%d
",ans);
51 return 0;
52 }
View Code
bzoj1305
贪心即可(不会证明,可能是错的)
1 #include <cstdio>
2
3 #define maxn 60
4 #define inf 0x3f3f3f3f
5
6 int a[maxn];
7
8 inline int min(int a,int b)
9 {
10 return a < b ? a : b;
11 }
12
13 int main()
14 {
15 int n,k;
16 scanf("%d%d
",&n,&k);
17 int ming=inf,minb=inf;
18 for (int i=1;i<=n;i++)
19 {
20 char ch;
21 int now=0;
22 for (int j=1;j<=n;j++)
23 {
24 ch=getchar();
25 if (ch == 'Y')
26 {
27 now++;
28 a[j]++;
29 }
30 }
31 while (ch=getchar(),ch != '
' && ch != '
');
32 minb=min(minb,now);
33 }
34 for (int i=1;i<=n;i++)
35 ming=min(ming,a[i]);
36 printf("%d
",min(n,min(ming,minb)+k));
37 return 0;
38 }
View Code
bzoj1406
n|(x^2-1)
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 1010
7
8 int ans[maxn];
9
10 int main()
11 {
12 int n,cnt=0;
13 scanf("%d",&n);
14 for (int i=1;i*i <= n;i++)
15 if (n%i == 0)
16 {
17 int x=n/i;
18 for (int j=1;j<=n;j+=x)
19 if ((j+1)%i == 0)
20 ans[++cnt]=j;
21 for (int j=x-1;j<=n;j+=x)
22 if ((j-1)%i == 0)
23 ans[++cnt]=j;
24 }
25 sort(ans+1,ans+cnt+1);
26 cnt=unique(ans+1,ans+cnt+1)-ans-1;
27 if (!cnt)
28 puts("None");
29 else
30 for (int i=1;i<=cnt;i++)
31 printf("%d
",ans[i]);
32 return 0;
33 }
View Code
bzoj1412
典型的最小割模型
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 20010
8 #define maxm 1000010
9 #define s 0
10 #define t maxn-1
11 #define inf 0x3f3f3f3f
12
13 const int fx[]={0,1,0,-1};
14 const int fy[]={-1,0,1,0};
15
16 struct edge
17 {
18 int to,flow;
19 edge *next,*part;
20 }e[maxm],*head[maxn];
21
22 int ne=0;
23 int q[maxn],d[maxn];
24
25 inline void add(int from,int to,int flow)
26 {
27 e[ne].to=to;
28 e[ne].flow=flow;
29 e[ne].next=head[from];
30 head[from]=&e[ne++];
31 }
32
33 inline void add_edge(int from,int to,int flow)
34 {
35 e[ne].part=&e[ne+1];
36 e[ne+1].part=&e[ne];
37 add(from,to,flow);
38 add(to,from,0);
39 }
40
41 inline bool bfs()
42 {
43 memset(d,-1,sizeof(d));
44 int op=0,cls=1;
45 q[1]=s;
46 d[s]=0;
47 while (op !=cls)
48 {
49 int x=q[++op];
50 for (edge *p=head[x];p;p=p->next)
51 if (p->flow && d[p->to] == -1)
52 {
53 d[p->to]=d[x]+1;
54 q[++cls]=p->to;
55 }
56 }
57 return ~d[t];
58 }
59
60 inline int dfs(int now,int now_flow)
61 {
62 if (now == t)
63 return now_flow;
64 int out=now_flow;
65 for (edge *p=head[now];p;p=p->next)
66 if (p->flow && d[p->to] == d[now]+1 && out)
67 {
68 int f=dfs(p->to,min(p->flow,out));
69 p->flow-=f;
70 p->part->flow+=f;
71 out-=f;
72 }
73 if (out == now_flow)
74 d[now]=-1;
75 return now_flow-out;
76 }
77
78 inline int dinic()
79 {
80 int ans=0;
81 while (bfs())
82 ans+=dfs(s,inf);
83 return ans;
84 }
85
86 int map[110][110],pos[110][110];
87
88 int main()
89 {
90 int n,m;
91 scanf("%d%d",&n,&m);
92 for (int i=1;i<=n;i++)
93 for (int j=1;j<=m;j++)
94 {
95 scanf("%d",&map[i][j]);
96 pos[i][j]=(i-1)*m+j;
97 }
98 for (int i=1;i<=n;i++)
99 for (int j=1;j<=m;j++)
100 {
101 if (map[i][j] == 1)
102 add_edge(s,pos[i][j],inf);
103 if (map[i][j] == 2)
104 add_edge(pos[i][j],t,inf);
105 for (int k=0;k<4;k++)
106 {
107 int x=i+fx[k],y=j+fy[k];
108 if (x > 0 && x <= n && y > 0 && y <= m)
109 {
110 if (map[i][j] == 1 && map[x][y] == 0)
111 add_edge(pos[i][j],pos[x][y],1);
112 if (map[i][j] == 0 && map[x][y] == 2)
113 add_edge(pos[i][j],pos[x][y],1);
114 if (map[i][j] == 1 && map[x][y] == 2)
115 add_edge(pos[i][j],pos[x][y],1);
116 if (map[i][j] == 0 && map[x][y] == 0)
117 add_edge(pos[i][j],pos[x][y],1);
118 }
119 }
120 }
121 printf("%d
",dinic());
122 return 0;
123 }
View Code
bzoj1433
水水的二分图。。。人弱只能写dinic
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 510
8 #define maxm 1000010
9 #define s 0
10 #define t maxn-1
11 #define inf 0x3f3f3f3f
12
13 struct edge
14 {
15 int to,flow;
16 edge *next,*part;
17 }e[maxm],*head[maxn];
18
19 int ne=0;
20 int q[maxn],d[maxn];
21
22 inline void add(int from,int to,int flow)
23 {
24 e[ne].to=to;
25 e[ne].flow=flow;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 inline void add_edge(int from,int to,int flow)
31 {
32 e[ne].part=&e[ne+1];
33 e[ne+1].part=&e[ne];
34 add(from,to,flow);
35 add(to,from,0);
36 }
37
38 inline bool bfs()
39 {
40 memset(d,-1,sizeof(d));
41 int op=0,cls=1;
42 q[1]=s;
43 d[s]=0;
44 while (op != cls)
45 {
46 int x=q[++op];
47 for (edge *p=head[x];p;p=p->next)
48 if (p->flow && d[p->to] == -1)
49 {
50 d[p->to]=d[x]+1;
51 q[++cls]=p->to;
52 }
53 }
54 return ~d[t];
55 }
56
57 int dfs(int now,int now_flow)
58 {
59 if (now == t)
60 return now_flow;
61 int out=now_flow;
62 for (edge *p=head[now];p;p=p->next)
63 if (p->flow && d[p->to] == d[now]+1 && out)
64 {
65 int f=dfs(p->to,min(p->flow,out));
66 p->flow-=f;
67 p->part->flow+=f;
68 out-=f;
69 }
70 if (out == now_flow)
71 d[now]=-1;
72 return now_flow-out;
73 }
74
75 inline int dinic()
76 {
77 int ans=0;
78 while (bfs())
79 ans+=dfs(s,inf);
80 return ans;
81 }
82
83 int a[maxn];
84
85 int main()
86 {
87 int _;
88 scanf("%d",&_);
89 while (_--)
90 {
91 memset(head,0,sizeof(head));
92 ne=0;
93 int n;
94 int sum=0;
95 scanf("%d",&n);
96 for (int i=1;i<=n;i++)
97 {
98 scanf("%d",&a[i]);
99 if (a[i])
100 add_edge(i+n,t,1);
101 }
102 for (int i=1;i<=n;i++)
103 {
104 int x;
105 scanf("%d",&x);
106 if (!a[i])
107 {
108 add_edge(s,i,1);
109 sum++;
110 }
111 else
112 if (!x)
113 {
114 add_edge(s,i,1);
115 add_edge(i,i+n,1);
116 sum++;
117 }
118 }
119 for (int i=1;i<=n;i++)
120 for (int j=1;j<=n;j++)
121 {
122 int x;
123 scanf("%d",&x);
124 if (x)
125 add_edge(i,j+n,1);
126 }
127 if (dinic() == sum)
128 puts("^_^");
129 else
130 puts("T_T");
131 }
132 return 0;
133 }
View Code
bzoj1452
观察数据范围后二维树状数组
1 #include <cstdio>
2
3 #define maxn 310
4 #define maxc 110
5
6 int n,m;
7 int col[maxn][maxn];
8 int bit[maxc][maxn][maxn];
9
10 inline void bit_update(int c,int x,int y,int val)
11 {
12 for (int i=x;i<=n;i+=i&-i)
13 for (int j=y;j<=m;j+=j&-j)
14 bit[c][i][j]+=val;
15 }
16
17 inline int query(int c,int x,int y)
18 {
19 int ans=0;
20 for (int i=x;i;i-=i&-i)
21 for (int j=y;j;j-=j&-j)
22 ans+=bit[c][i][j];
23 return ans;
24 }
25
26 int main()
27 {
28 scanf("%d%d",&n,&m);
29 for (int i=1;i<=n;i++)
30 for (int j=1;j<=m;j++)
31 {
32 scanf("%d",&col[i][j]);
33 bit_update(col[i][j],i,j,1);
34 }
35 int _;
36 scanf("%d",&_);
37 while (_--)
38 {
39 int now;
40 scanf("%d",&now);
41 if (now == 1)
42 {
43 int x,y,c;
44 scanf("%d%d%d",&x,&y,&c);
45 bit_update(col[x][y],x,y,-1);
46 col[x][y]=c;
47 bit_update(col[x][y],x,y,1);
48 }
49 else
50 {
51 int x1,x2,y1,y2,c;
52 scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&c);
53 printf("%d
",query(c,x2,y2)-query(c,x1-1,y2)-query(c,x2,y1-1)+query(c,x1-1,y1-1));
54 }
55 }
56 return 0;
57 }
View Code
bzoj1485
卡特兰数
1 #include <cstdio>
2
3 #define maxn 2000010
4
5 long long cnt=0;
6 long long p[maxn];
7 long long mod;
8 bool prime[maxn];
9
10 inline void get_prime(long long n)
11 {
12 for (long long i=2;i<=n;i++)
13 {
14 if (!prime[i])
15 p[++cnt]=i;
16 for (long long j=1;j<=cnt && p[j]*i <= n;j++)
17 {
18 prime[i*p[j]]=1;
19 if (i%p[j] == 0)
20 break;
21 }
22 }
23 }
24
25 inline long long pow(long long a,long long b)
26 {
27 long long ans=1,wk=a;
28 for (;b;b>>=1)
29 {
30 if (b&1)
31 (ans*=wk)%=mod;
32 (wk*=wk)%=mod;
33 }
34 return ans;
35 }
36
37 int main()
38 {
39 long long n;
40 scanf("%lld%lld",&n,&mod);
41 get_prime(n*2);
42 long long ans=1;
43 for (long long i=1;i<=cnt;i++)
44 {
45 long long now=0;
46 for (long long j=p[i];j<=2*n;j*=p[i])
47 now+=(2*n)/j-2*(n/j);
48 if ((n+1)%p[i] == 0)
49 for (long long j=n+1;j%p[i] == 0;j/=p[i])
50 now--;
51 (ans*=pow(p[i],now))%=mod;
52 }
53 printf("%lld
",ans);
54 return 0;
55 }
View Code
bzoj1486
二分+spfa找负环
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 3010
8 #define maxm 10010
9 #define inf 1e+9
10
11 struct edge
12 {
13 int to;
14 double dist;
15 edge *next;
16 }e[maxm],*head[maxn];
17
18 int n,m;
19 int ne=0;
20 int q[maxn];
21 double d[maxn];
22 int from[maxm],to[maxm];
23 double dist[maxm];
24 int now[maxn];
25 bool flag[maxn];
26
27 inline void add_edge(int from,int to,double dist)
28 {
29 e[ne].to=to;
30 e[ne].dist=dist;
31 e[ne].next=head[from];
32 head[from]=&e[ne++];
33 }
34
35 inline bool spfa()
36 {
37 memset(now,0,sizeof(now));
38 memset(flag,0,sizeof(flag));
39 for (int i=1;i<=n;i++)
40 d[i]=inf;
41 d[1]=0;
42 int op=0,cls=1;
43 q[1]=1;
44 now[1]=1;
45 flag[1]=1;
46 while (op != cls)
47 {
48 op++;
49 if (op == maxn)
50 op=0;
51 int x=q[op];
52 flag[x]=0;
53 for (edge *p=head[x];p;p=p->next)
54 if (d[p->to] > d[x]+p->dist)
55 {
56 d[p->to]=d[x]+p->dist;
57 if (!flag[p->to])
58 {
59 now[p->to]++;
60 if (now[p->to] > 15)
61 return 1;
62 cls++;
63 if (cls == maxn)
64 cls=0;
65 q[cls]=p->to;
66 flag[p->to]=1;
67 }
68 }
69 }
70 return 0;
71 }
72
73 int main()
74 {
75 scanf("%d%d",&n,&m);
76 for (int i=1;i<=m;i++)
77 scanf("%d%d%lf",&from[i],&to[i],&dist[i]);
78 double l=-inf,r=inf,ans=0.0;
79 for (int t=1;t<=60;t++)
80 {
81 double mid=(l+r)/2;
82 ne=0;
83 memset(head,0x0,sizeof(head));
84 for (int i=1;i<=m;i++)
85 add_edge(from[i],to[i],dist[i]-mid);
86 if (spfa())
87 {
88 ans=mid;
89 r=mid;
90 }
91 else
92 l=mid;
93 }
94 printf("%.8lf
",ans);
95 return 0;
96 }
View Code
bzoj1497
最小割模型
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 100010
8 #define maxm 1000010
9 #define s 0
10 #define t maxn-1
11 #define inf 0x3f3f3f3f
12
13 struct edge
14 {
15 int to,flow;
16 edge *next,*part;
17 }e[maxm],*head[maxn];
18
19 int ne=0;
20 int q[maxn],d[maxn];
21
22 inline void add(int from,int to,int flow)
23 {
24 e[ne].to=to;
25 e[ne].flow=flow;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 inline void add_edge(int from,int to,int flow)
31 {
32 e[ne].part=&e[ne+1];
33 e[ne+1].part=&e[ne];
34 add(from,to,flow);
35 add(to,from,0);
36 }
37
38 inline bool bfs()
39 {
40 memset(d,-1,sizeof(d));
41 int op=0,cls=1;
42 q[1]=s;
43 d[s]=0;
44 while (op != cls)
45 {
46 int x=q[++op];
47 for (edge *p=head[x];p;p=p->next)
48 if (p->flow && d[p->to] == -1)
49 {
50 q[++cls]=p->to;
51 d[p->to]=d[x]+1;
52 }
53 }
54 return d[t] != -1;
55 }
56
57 int dfs(int now,int now_flow)
58 {
59 if (now == t)
60 return now_flow;
61 int out=now_flow;
62 for (edge *p=head[now];p;p=p->next)
63 if (p->flow && d[p->to] == d[now]+1 && out)
64 {
65 int f=dfs(p->to,min(p->flow,out));
66 p->flow-=f;
67 p->part->flow+=f;
68 out-=f;
69 }
70 if (out == now_flow)
71 d[now]=-1;
72 return now_flow-out;
73 }
74
75 inline int dinic()
76 {
77 int ans=0;
78 while (bfs())
79 ans+=dfs(s,inf);
80 return ans;
81 }
82
83 int main()
84 {
85 int n,m,sum=0;
86 scanf("%d%d",&n,&m);
87 for (int i=1;i<=n;i++)
88 {
89 int x;
90 scanf("%d",&x);
91 add_edge(i+m,t,x);
92 }
93 for (int i=1;i<=m;i++)
94 {
95 int x,y,z;
96 scanf("%d%d%d",&x,&y,&z);
97 sum+=z;
98 add_edge(i,x+m,inf);
99 add_edge(i,y+m,inf);
100 add_edge(s,i,z);
101 }
102 printf("%d
",sum-dinic());
103 return 0;
104 }
View Code
bzoj1500
神级splay,不过真正想清楚了两个小时足够写完了,也可以用块链
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 500010
7 #define inf 0x3f3f3f3f
8
9 struct Node
10 {
11 int sum,lmax,rmax,max,lazy,size,v;
12 bool rot;
13 Node *s[2],*par;
14
15 inline Node()
16 {
17 lmax=rmax=max=lazy=-inf;
18 v=sum=size=rot=0;
19 }
20
21 inline bool S()
22 {
23 return this == par->s[1];
24 }
25 };
26
27 struct splay
28 {
29 Node t[maxn],null;
30 Node *root,*sta[maxn];
31 int top;
32
33 inline splay()
34 {
35 null.s[0]=null.s[1]=null.par=&null;
36 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2;
37 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1;
38 top=0;
39 for (int i=2;i<maxn;i++)
40 sta[++top]=&t[i];
41 root=&t[0];
42 }
43
44 inline Node* new_Node(int v)
45 {
46 Node* now=sta[top--];
47 now->lmax=now->rmax=now->max=now->v=now->sum=v;
48 now->lazy=-inf;
49 now->rot=0;
50 now->s[0]=now->s[1]=now->par=&null;
51 now->size=1;
52 return now;
53 }
54
55 void erase(Node* now)
56 {
57 if (now->s[0] != &null)
58 erase(now->s[0]);
59 if (now->s[1] != &null)
60 erase(now->s[1]);
61 sta[++top]=now;
62 }
63
64 inline void _pushdown(Node* now)
65 {
66 if (now->rot)
67 {
68 swap(now->s[0],now->s[1]);
69 swap(now->s[0]->lmax,now->s[0]->rmax);
70 swap(now->s[1]->lmax,now->s[1]->rmax);
71 now->s[0]->rot^=1;
72 now->s[1]->rot^=1;
73 now->rot^=1;
74 }
75 if (now->lazy != -inf)
76 {
77 int add=now->lazy;
78 now->s[0]->lazy=now->s[0]->v=add;
79 now->s[0]->sum=add*now->s[0]->size;
80 now->s[0]->lmax=now->s[0]->rmax=now->s[0]->max=max(add,add*now->s[0]->size);
81 now->s[1]->lazy=now->s[1]->v=add;
82 now->s[1]->sum=add*now->s[1]->size;
83 now->s[1]->lmax=now->s[1]->rmax=now->s[1]->max=max(add,add*now->s[1]->size);
84 now->lazy=-inf;
85 null.lmax=null.rmax=null.max=null.lazy=-inf;
86 null.v=null.sum=0;
87 }
88 }
89
90 inline void _update(Node* now)
91 {
92 if (now == &null)
93 return;
94 null.lmax=null.rmax=null.max=-inf;
95 now->lmax=max(now->s[0]->lmax,now->s[0]->sum+now->v+max(now->s[1]->lmax,0));
96 now->rmax=max(now->s[1]->rmax,now->s[1]->sum+now->v+max(now->s[0]->rmax,0));
97 now->max=max(max(now->s[0]->max,now->s[1]->max),now->v+max(now->s[0]->rmax,0)+max(now->s[1]->lmax,0));
98 now->sum=now->s[0]->sum+now->s[1]->sum+now->v;
99 now->size=now->s[0]->size+now->s[1]->size+1;
100 }
101
102 inline void _rot(Node* now)
103 {
104 Node* p=now->par;
105 int l=now->S(),r=!l;
106 (p->s[l]=now->s[r])->par=p;
107 now->par=p->par;
108 if (p->par != &null)
109 p->par->s[p->S()]=now;
110 (now->s[r]=p)->par=now;
111 _update(p);
112 _update(now);
113 }
114
115 void _relax(Node* now)
116 {
117 if (now->par != &null)
118 _relax(now->par);
119 _pushdown(now);
120 }
121
122 inline void _splay(Node* now,Node* goal)
123 {
124 _relax(now);
125 while (now->par != goal)
126 {
127 if (now->par->par == goal)
128 {
129 _rot(now);
130 break;
131 }
132 if (now->S() == now->par->S())
133 {
134 _rot(now->par);
135 _rot(now);
136 }
137 else
138 {
139 _rot(now);
140 _rot(now);
141 }
142 }
143 if (goal == &null)
144 root=now;
145 }
146
147 inline Node* _select(int v)
148 {
149 Node* now=root;
150 while (1)
151 {
152 _pushdown(now);
153 if (now->s[0]->size+1 == v)
154 return now;
155 if (v <= now->s[0]->size)
156 now=now->s[0];
157 else
158 {
159 v-=now->s[0]->size+1;
160 now=now->s[1];
161 }
162 }
163 }
164
165 inline void insert(int* r,int pos,int len)
166 {
167 Node* p=_select(pos+1);
168 Node* q=_select(pos+2);
169 _splay(p,&null);
170 _splay(q,root);
171 Node* now=new_Node(r[1]);
172 (now->par=q)->s[0]=now;
173 Node* par=now;
174 for (int i=2;i<=len;i++)
175 {
176 now=new_Node(r[i]);
177 (now->par=par)->s[1]=now;
178 now->size=len-i+1;
179 par=now;
180 }
181 _splay(now,&null);
182 }
183
184 inline void del(int pos,int len)
185 {
186 Node* p=_select(pos);
187 Node* q=_select(pos+len+1);
188 _splay(p,&null);
189 _splay(q,root);
190 erase(q->s[0]);
191 q->s[0]=&null;
192 _update(q);
193 _update(p);
194 }
195
196 inline void change(int pos,int len,int val)
197 {
198 Node* p=_select(pos);
199 Node* q=_select(pos+len+1);
200 _splay(p,&null);
201 _splay(q,root);
202 Node* now=q->s[0];
203 now->lazy=now->v=val;
204 now->sum=val*now->size;
205 now->lmax=now->rmax=now->max=max(val,val*now->size);
206 _update(q);
207 _update(p);
208 }
209
210 inline void rot(int pos,int len)
211 {
212 Node* p=_select(pos);
213 Node* q=_select(pos+len+1);
214 _splay(p,&null);
215 _splay(q,root);
216 Node* now=q->s[0];
217 now->rot^=1;
218 swap(now->lmax,now->rmax);
219 _update(q);
220 _update(p);
221 }
222
223 inline int query_sum(int pos,int len)
224 {
225 Node* p=_select(pos);
226 Node* q=_select(pos+len+1);
227 _splay(p,&null);
228 _splay(q,root);
229 return q->s[0]->sum;
230 }
231
232 inline int query_max()
233 {
234 Node* p=&t[0];
235 Node* q=&t[1];
236 _splay(p,&null);
237 _splay(q,root);
238 return q->s[0]->max;
239 }
240
241 void travel(Node* now)
242 {
243 _pushdown(now);
244 if (now->s[0] != &null)
245 travel(now->s[0]);
246 printf("%d ",now->v);
247 if (now->s[1] != &null)
248 travel(now->s[1]);
249 }
250 }t;
251
252 int a[maxn];
253
254 int main()
255 {
256 int n,_;
257 scanf("%d%d",&n,&_);
258 for (int i=1;i<=n;i++)
259 scanf("%d",&a[i]);
260 t.insert(a,0,n);
261 while (_--)
262 {
263 char s[20];
264 int pos,len;
265 scanf("%s",s);
266 if (s[0] == 'I')
267 {
268 scanf("%d%d",&pos,&len);
269 for (int i=1;i<=len;i++)
270 scanf("%d",&a[i]);
271 t.insert(a,pos,len);
272 }
273 if (s[0] == 'D')
274 {
275 scanf("%d%d",&pos,&len);
276 t.del(pos,len);
277 }
278 if (s[0] == 'M' && s[2] == 'K')
279 {
280 int x;
281 scanf("%d%d%d",&pos,&len,&x);
282 t.change(pos,len,x);
283 }
284 if (s[0] == 'R')
285 {
286 scanf("%d%d",&pos,&len);
287 t.rot(pos,len);
288 }
289 if (s[0] == 'G')
290 {
291 scanf("%d%d",&pos,&len);
292 printf("%d
",t.query_sum(pos,len));
293 }
294 if (s[0] == 'M' && s[2] == 'X')
295 printf("%d
",t.query_max());
296 }
297 return 0;
298 }
View Code
bzoj1503
裸的平衡树,可以打全局标记
1 #include <cstdio>
2
3 const int maxn=100010;
4
5 int n,min,add;
6
7 struct Node
8 {
9 int size,v;
10 Node *s[2];
11 Node()
12 {
13 size=v=0;
14 }
15 };
16
17 struct sbt
18 {
19 Node t[maxn],null;
20 Node *root;
21 int ne;
22
23 sbt()
24 {
25 ne=0;
26 null.s[0]=null.s[1]=&null;
27 root=&null;
28 }
29
30 inline void _rot(Node* &now,int l)
31 {
32 int r=!l;
33 Node *s=now->s[l];
34 now->s[l]=s->s[r];
35 s->s[r]=now;
36 s->size=now->size;
37 now->size=now->s[0]->size+now->s[1]->size+1;
38 now=s;
39 }
40
41 void _maintain(Node* &now,int l)
42 {
43 int r=!l;
44 if (now->s[l]->s[l]->size > now->s[r]->size)
45 _rot(now,l);
46 else
47 {
48 if (now->s[l]->s[r]->size > now->s[r]->size)
49 {
50 _rot(now->s[l],r);
51 _rot(now,l);
52 }
53 else
54 return;
55 }
56 _maintain(now->s[0],0);
57 _maintain(now->s[1],1);
58 _maintain(now,0);
59 _maintain(now,1);
60 }
61
62 void insert(Node* &now,int v)
63 {
64 if (now == &null)
65 {
66 now=&t[++ne];
67 now->v=v;
68 now->size=1;
69 now->s[0]=now->s[1]=&null;
70 return;
71 }
72 now->size++;
73 if (v < now->v)
74 insert(now->s[0],v);
75 else
76 insert(now->s[1],v);
77 _maintain(now,v >= now->v);
78 }
79
80 void del(Node* &now)
81 {
82 if (now == &null)
83 return;
84 if (now->v+add < min)
85 {
86 now=now->s[1];
87 del(now);
88 }
89 else
90 {
91 del(now->s[0]);
92 now->size=now->s[0]->size+now->s[1]->size+1;
93 }
94 }
95
96 inline int find(int v)
97 {
98 Node* now=root;
99 while (1)
100 {
101 if (now == &null)
102 return -1;
103 if (now->s[1]->size+1 == v)
104 return now->v+add;
105 if (v <= now->s[1]->size)
106 now=now->s[1];
107 else
108 {
109 v-=now->s[1]->size+1;
110 now=now->s[0];
111 }
112 }
113 }
114
115 void travel(Node* now)
116 {
117 if (now->s[0] != &null)
118 travel(now->s[0]);
119 printf("%d
",now->v+add);
120 if (now->s[1] != &null)
121 travel(now->s[1]);
122 }
123 }t;
124
125 int main()
126 {
127 // freopen("1.in","r",stdin);
128 // freopen("1.out","w",stdout);
129 scanf("%d%d",&n,&min);
130 char s[2];
131 int x;
132 while (n--)
133 {
134 scanf("%s%d",s,&x);
135 if (s[0] == 'I')
136 if (x >= min)
137 t.insert(t.root,x-add);
138 if (s[0] == 'A')
139 add+=x;
140 if (s[0] == 'S')
141 {
142 add-=x;
143 t.del(t.root);
144 }
145 if (s[0] == 'F')
146 printf("%d
",t.find(x));
147 }
148 printf("%d
",t.ne-t.root->size);
149 return 0;
150 }
View Code
bzoj1507
1269弱化版,我同学get的时候爆栈了的说。。。表示不能理解。。。
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 3*1024*1024
7
8 struct Node
9 {
10 char ch;
11 int size;
12 Node *s[2],*par;
13
14 inline bool S()
15 {
16 return this == par->s[1];
17 }
18 };
19
20 struct splay
21 {
22 Node t[maxn],null;
23 Node *root;
24 int ne;
25
26 splay()
27 {
28 null.s[0]=null.s[1]=null.par=&null;
29 null.size=null.ch=0;
30 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2;t[0].ch='s';
31 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1;t[1].ch='b';
32 ne=2;
33 root=&t[0];
34 }
35
36 inline Node* new_Node()
37 {
38 Node* now=&t[ne++];
39 now->s[0]=now->s[1]=now->par=&null;
40 return now;
41 }
42
43 inline void _update(Node* now)
44 {
45 now->size=now->s[0]->size+now->s[1]->size+1;
46 }
47
48 inline void _rot(Node* now)
49 {
50 Node* p=now->par;
51 int l=now->S(),r=!l;
52 (p->s[l]=now->s[r])->par=p;
53 now->par=p->par;
54 if (p->par != &null)
55 p->par->s[p->S()]=now;
56 (now->s[r]=p)->par=now;
57 _update(p);
58 _update(now);
59 }
60
61 inline void _splay(Node* now,Node* goal)
62 {
63 while (now->par != goal)
64 {
65 if (now->par->par == goal)
66 {
67 _rot(now);
68 break;
69 }
70 if (now->par->S() == now->S())
71 {
72 _rot(now->par);
73 _rot(now);
74 }
75 else
76 {
77 _rot(now);
78 _rot(now);
79 }
80 }
81 if (goal == &null)
82 root=now;
83 }
84
85 inline Node* _select(int v)
86 {
87 Node* now=root;
88 while (1)
89 {
90 if (now->s[0]->size+1 == v)
91 return now;
92 if (v <= now->s[0]->size)
93 now=now->s[0];
94 else
95 {
96 v-=now->s[0]->size+1;
97 now=now->s[1];
98 }
99 }
100 }
101
102 inline void insert(int pos,int len)
103 {
104 Node* p=_select(pos+1);
105 Node* q=_select(pos+2);
106 _splay(p,&null);
107 _splay(q,root);
108 static char s[maxn];
109 for (int i=1;i<=len;i++)
110 while (s[i]=getchar(),s[i] == '
' || s[i] == '
');
111 Node* now=new_Node();
112 now->ch=s[1];
113 (q->s[0]=now)->par=q;
114 now->size=len;
115 q->size+=len;
116 p->size+=len;
117 Node* par=now;
118 for (int i=2;i<=len;i++)
119 {
120 Node* now=new_Node();
121 now->ch=s[i];
122 (par->s[1]=now)->par=par;
123 now->size=len-i+1;
124 par=now;
125 }
126 _splay(now,&null);
127 }
128
129 inline void del(int pos,int len)
130 {
131 Node* p=_select(pos+1);
132 Node* q=_select(min(root->size,pos+len+2));
133 _splay(p,&null);
134 _splay(q,root);
135 q->s[0]=&null;
136 _update(q);
137 _update(p);
138 }
139
140 void travel(Node* now)
141 {
142 if (now->s[0] != &null)
143 travel(now->s[0]);
144 putchar(now->ch);
145 if (now->s[1] != &null)
146 travel(now->s[1]);
147 }
148
149 inline void get(int pos,int len)
150 {
151 Node* p=_select(pos+1);
152 Node* q=_select(min(pos+len+2,root->size));
153 _splay(p,&null);
154 _splay(q,root);
155 travel(q->s[0]);
156 }
157 }t;
158
159 int main()
160 {
161 int pos=0;
162 int _;
163 scanf("%d",&_);
164 while (_--)
165 {
166 char s[10];
167 int x;
168 scanf("%s",s);
169 if (s[0] == 'M')
170 {
171 scanf("%d",&x);
172 pos=x;
173 }
174 if (s[0] == 'I')
175 {
176 scanf("%d",&x);
177 t.insert(pos,x);
178 }
179 if (s[0] == 'D')
180 {
181 scanf("%d",&x);
182 t.del(pos,x);
183 }
184 if (s[0] == 'G')
185 {
186 scanf("%d",&x);
187 t.get(pos,x);
188 puts("");
189 }
190 if (s[0] == 'P')
191 pos--;
192 if (s[0] == 'N')
193 pos++;
194 }
195 return 0;
196 }
View Code
bzoj1588
又是裸的平衡树。。。
1 #include <cstdio>
2
3 const int maxn=100010;
4 const int inf=0x3f3f3f3f;
5
6 struct Node
7 {
8 Node* s[2];
9 int size,v;
10 };
11
12 struct sbt
13 {
14 Node t[maxn],null;
15 Node* root;
16 int ne;
17
18 sbt()
19 {
20 null.s[0]=null.s[1]=&null;
21 null.v=null.size=0;
22 ne=0;
23 root=&null;
24 }
25
26 inline void _rot(Node* &now,int l)
27 {
28 int r=!l;
29 Node* s=now->s[l];
30 s->size=now->size;
31 now->s[l]=s->s[r];
32 s->s[r]=now;
33 now->size=now->s[0]->size+now->s[1]->size+1;
34 now=s;
35 }
36
37 void _maintain(Node* &now,int l)
38 {
39 int r=!l;
40 if (now->s[l]->s[l]->size > now->s[r]->size)
41 _rot(now,l);
42 else
43 {
44 if (now->s[l]->s[r]->size > now->s[r]->size)
45 {
46 _rot(now->s[l],r);
47 _rot(now,l);
48 }
49 else
50 return;
51 }
52 _maintain(now->s[0],0);
53 _maintain(now->s[1],1);
54 _maintain(now,0);
55 _maintain(now,1);
56 }
57
58 void insert(Node* &now,int v)
59 {
60 if (now == &null)
61 {
62 now=&t[ne++];
63 now->v=v;
64 now->size=1;
65 now->s[0]=now->s[1]=&null;
66 return;
67 }
68 now->size++;
69 if (v >= now->v)
70 insert(now->s[1],v);
71 else
72 insert(now->s[0],v);
73 _maintain(now,v >= now->v);
74 }
75
76 inline int pred(int v)
77 {
78 int ans=-inf;
79 Node* now=root;
80 while (1)
81 {
82 if (now == &null)
83 break;
84 if (v < now->v)
85 now=now->s[0];
86 else
87 {
88 ans=now->v;
89 now=now->s[1];
90 }
91 }
92 return ans;
93 }
94
95 inline int suc(int v)
96 {
97 int ans=inf;
98 Node* now=root;
99 while (1)
100 {
101 if (now == &null)
102 break;
103 if (v > now->v)
104 now=now->s[1];
105 else
106 {
107 ans=now->v;
108 now=now->s[0];
109 }
110 }
111 return ans;
112 }
113 }t;
114
115 inline int min(int a,int b)
116 {
117 if (a < b)
118 return a;
119 return b;
120 }
121
122 inline int abs(int x)
123 {
124 if (x >= 0)
125 return x;
126 return -x;
127 }
128
129 int main()
130 {
131 int n,x;
132 int sum=0;
133 scanf("%d",&n);
134 scanf("%d",&x);
135 sum=x;
136 t.insert(t.root,x);
137 for (int i=2;i<=n;i++)
138 {
139 x=0;
140 scanf("%d",&x);
141 sum+=min(abs(x-t.pred(x)),abs(t.suc(x)-x));
142 t.insert(t.root,x);
143 }
144 printf("%d",sum);
145 return 0;
146 }
View Code
bzoj1610(已隐藏)
水题不能多说,凑AC数用的。。。
1 #include <cstdio>
2 #include <cmath>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 210
8 #define eps 1e-8
9
10 int cnt=0;
11 double a[maxn*maxn],x[maxn],y[maxn];
12
13 int main()
14 {
15 int n;
16 scanf("%d",&n);
17 for (int i=1;i<=n;i++)
18 scanf("%lf%lf",&x[i],&y[i]);
19 int ans=0;
20 for (int i=1;i<n;i++)
21 for (int j=i+1;j<=n;j++)
22 if (fabs(x[i]-x[j]) < eps)
23 ans=1;
24 else
25 a[++cnt]=(y[i]-y[j])/(x[i]-x[j]);
26 sort(a+1,a+cnt+1);
27 a[0]=a[1]-1;
28 for (int i=1;i<=cnt;i++)
29 if (a[i]-a[i-1] > eps)
30 ans++;
31 printf("%d
",ans);
32 return 0;
33 }
View Code
bzoj1612(已隐藏)
两边BFS即可,注意重新加边时的清零
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 110
5 #define maxm 5010
6
7 struct edge
8 {
9 int to;
10 edge *next;
11 }e[maxm],*head[maxn];
12
13 int ne=0;
14 int q[maxn];
15 int from[maxm],to[maxm];
16 int now[maxn];
17 bool flag[maxn];
18
19 inline void add_edge(int from,int to)
20 {
21 e[ne].to=to;
22 e[ne].next=head[from];
23 head[from]=&e[ne++];
24 }
25
26 inline int bfs(int now)
27 {
28 int op=0,cls=1;
29 q[1]=now;
30 int ans=0;
31 while (op != cls)
32 {
33 int x=q[++op];
34 for (edge *p=head[x];p;p=p->next)
35 if (!flag[p->to])
36 {
37 flag[p->to]=1;
38 q[++cls]=p->to;
39 ans++;
40 }
41 }
42 return ans;
43 }
44
45 int main()
46 {
47 int n,m;
48 scanf("%d%d",&n,&m);
49 for (int i=1;i<=m;i++)
50 scanf("%d%d",&from[i],&to[i]);
51 for (int i=1;i<=m;i++)
52 add_edge(from[i],to[i]);
53 for (int i=1;i<=n;i++)
54 {
55 memset(flag,0,sizeof(flag));
56 flag[i]=1;
57 now[i]+=bfs(i);
58 }
59 memset(head,0,sizeof(head));
60 ne=0;
61 for (int i=1;i<=m;i++)
62 add_edge(to[i],from[i]);
63 int ans=0;
64 for (int i=1;i<=n;i++)
65 {
66 memset(flag,0,sizeof(flag));
67 flag[i]=1;
68 now[i]+=bfs(i);
69 if (now[i] == n-1)
70 ans++;
71 }
72 printf("%d
",ans);
73 return 0;
74 }
View Code
bzoj1616(已隐藏)
暴力DP
1 #include <cstdio>
2
3 #define maxn 110
4
5 const int fx[]={0,1,0,-1};
6 const int fy[]={1,0,-1,0};
7
8 bool map[maxn][maxn];
9 int f[maxn][maxn][20];
10
11 int main()
12 {
13 int n,m,t,sx,sy,tx,ty;
14 scanf("%d%d%d",&n,&m,&t);
15 for (int i=1;i<=n;i++)
16 for (int j=1;j<=m;j++)
17 {
18 char ch;
19 while (ch=getchar(),ch != '.' && ch != '*');
20 if (ch == '.')
21 map[i][j]=1;
22 else
23 map[i][j]=0;
24 }
25 scanf("%d%d%d%d",&sx,&sy,&tx,&ty);
26 f[sx][sy][0]=1;
27 for (int k=1;k<=t;k++)
28 for (int i=1;i<=n;i++)
29 for (int j=1;j<=m;j++)
30 if (map[i][j])
31 for (int p=0;p<4;p++)
32 {
33 int x=i+fx[p],y=j+fy[p];
34 if (map[x][y])
35 f[i][j][k]+=f[x][y][k-1];
36 }
37 printf("%d
",f[tx][ty][t]);
38 return 0;
39 }
View Code
bzoj1633(已隐藏)
挺好玩的字符串+DP
1 #include <cstdio>
2 #include <cstring>
3
4 #define inf 0x3f3f3f3f
5 #define maxn 610
6
7 int n,len,l[maxn];
8 char s[maxn];
9 char ch[maxn][30];
10 int f[maxn];
11
12 inline int min(int a,int b)
13 {
14 return a < b ? a : b;
15 }
16
17 inline int find(int pos,int x)
18 {
19 int l1=pos;
20 int l2=0;
21 while (l1 < len && l2 < l[x])
22 {
23 if (s[l1] == ch[x][l2])
24 l2++;
25 l1++;
26 }
27 if (l2 < l[x])
28 return inf;
29 return l1;
30 }
31
32 int main()
33 {
34 scanf("%d%d",&n,&len);
35 scanf("%s",s);
36 for (int i=1;i<=n;i++)
37 {
38 scanf("%s",ch[i]);
39 l[i]=strlen(ch[i]);
40 }
41 memset(f,0,sizeof(f));
42 for (int i=len-1;i>=0;i--)
43 {
44 f[i]=f[i+1]+1;
45 for (int j=1;j<=n;j++)
46 {
47 int pos=find(i,j);
48 if (pos != inf)
49 f[i]=min(f[i],f[pos]+pos-i-l[j]);
50 }
51 }
52 printf("%d
",f[0]);
53 return 0;
54 }
View Code
bzoj1636(已隐藏)
裸st
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 50010
7
8 int n,m;
9 int a[maxn];
10 int bit[30];
11 int fmax[maxn][20],fmin[maxn][20];
12
13 inline int max(int a,int b)
14 {
15 return a > b ? a : b;
16 }
17
18 inline int min(int a,int b)
19 {
20 return a < b ? a : b;
21 }
22
23 inline void st_pre()
24 {
25 for (int i=1;i<=n;i++)
26 fmin[i][0]=fmax[i][0]=a[i];
27 int k=lower_bound(bit,bit+20,n)-bit;
28 for (int j=1;j<=k;j++)
29 for (int i=1;i+bit[j]-1 <= n;i++)
30 {
31 fmin[i][j]=min(fmin[i][j-1],fmin[i+bit[j-1]][j-1]);
32 fmax[i][j]=max(fmax[i][j-1],fmax[i+bit[j-1]][j-1]);
33 }
34 }
35
36 inline int query(int l,int r)
37 {
38 int len=r-l+1;
39 int k=lower_bound(bit,bit+20,len)-bit;
40 int Max=max(fmax[l][k-1],fmax[r-bit[k-1]+1][k-1]);
41 int Min=min(fmin[l][k-1],fmin[r-bit[k-1]+1][k-1]);
42 return Max-Min;
43 }
44
45 int main()
46 {
47 bit[0]=1;
48 for (int i=1;i<=20;i++)
49 bit[i]=bit[i-1]+bit[i-1];
50 scanf("%d%d",&n,&m);
51 for (int i=1;i<=n;i++)
52 scanf("%d",&a[i]);
53 st_pre();
54 for (int i=1;i<=m;i++)
55 {
56 int x,y;
57 scanf("%d%d",&x,&y);
58 if (x > y)
59 x^=y^=x^=y;
60 printf("%d
",query(x,y));
61 }
62 return 0;
63 }
View Code
bzoj1666(已隐藏)
普及组?这道题拿来玩压代码长度游戏还不错。。。
1 #include <cstdio>
2
3 int ans=0,x;
4
5 int main()
6 {
7 scanf("%d",&x);
8 while (x != 1)
9 {
10 if (x & 1)
11 (x*=3)+=1;
12 else
13 x>>=1;
14 ans++;
15 }
16 printf("%d
",ans);
17 return 0;
18 }
View Code
bzoj1668(已隐藏)
水水的DP
1 #include <cstdio>
2
3 #define maxn 110
4
5 int n,m;
6 int a[maxn][maxn],f[maxn][maxn];
7
8 inline int max(int a,int b)
9 {
10 return a > b ? a : b;
11 }
12
13 inline int min(int a,int b)
14 {
15 return a < b ? a : b;
16 }
17
18 int main()
19 {
20 scanf("%d%d",&n,&m);
21 for (int i=1;i<=n;i++)
22 for (int j=1;j<=m;j++)
23 scanf("%d",&a[i][j]);
24 for (int i=1;i<=m;i++)
25 for (int j=1;j<=min(i,n);j++)
26 f[j][i]=max(max(f[j-1][i-1],f[j][i-1]),f[j+1][i-1])+a[j][i];
27 printf("%d
",f[n][m]);
28 return 0;
29 }
View Code
bzoj1699(已隐藏)
还是st。。。
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 50010
7
8 int n,m;
9 int a[maxn];
10 int bit[30];
11 int fmax[maxn][20],fmin[maxn][20];
12
13 inline int max(int a,int b)
14 {
15 return a > b ? a : b;
16 }
17
18 inline int min(int a,int b)
19 {
20 return a < b ? a : b;
21 }
22
23 inline void st_pre()
24 {
25 for (int i=1;i<=n;i++)
26 fmin[i][0]=fmax[i][0]=a[i];
27 int k=lower_bound(bit,bit+20,n)-bit;
28 for (int j=1;j<=k;j++)
29 for (int i=1;i+bit[j]-1 <= n;i++)
30 {
31 fmin[i][j]=min(fmin[i][j-1],fmin[i+bit[j-1]][j-1]);
32 fmax[i][j]=max(fmax[i][j-1],fmax[i+bit[j-1]][j-1]);
33 }
34 }
35
36 inline int query(int l,int r)
37 {
38 int len=r-l+1;
39 int k=lower_bound(bit,bit+20,len)-bit;
40 int Max=max(fmax[l][k-1],fmax[r-bit[k-1]+1][k-1]);
41 int Min=min(fmin[l][k-1],fmin[r-bit[k-1]+1][k-1]);
42 return Max-Min;
43 }
44
45 int main()
46 {
47 bit[0]=1;
48 for (int i=1;i<=20;i++)
49 bit[i]=bit[i-1]+bit[i-1];
50 scanf("%d%d",&n,&m);
51 for (int i=1;i<=n;i++)
52 scanf("%d",&a[i]);
53 st_pre();
54 for (int i=1;i<=m;i++)
55 {
56 int x,y;
57 scanf("%d%d",&x,&y);
58 if (x > y)
59 x^=y^=x^=y;
60 printf("%d
",query(x,y));
61 }
62 return 0;
63 }
View Code
bzoj1717(已隐藏)
后缀数组+二分
1 #include <cstdio>
2
3 #define maxn 1000010
4
5 int n,k;
6 int a[maxn],sa[maxn];
7
8 int wa[maxn],wb[maxn],wv[maxn],ws[maxn];
9
10 int cmp(int *r,int a,int b,int l)
11 {return r[a]==r[b]&&r[a+l]==r[b+l];}
12
13 inline void da(int *r,int *sa,int n,int m)
14 {
15 int i,j,p,*x=wa,*y=wb,*t;
16 for(i=0;i<m;i++) ws[i]=0;
17 for(i=0;i<n;i++) ws[x[i]=r[i]]++;
18 for(i=1;i<m;i++) ws[i]+=ws[i-1];
19 for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;
20 for(j=1,p=1;p<n;j*=2,m=p)
21 {
22 for(p=0,i=n-j;i<n;i++) y[p++]=i;
23 for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
24 for(i=0;i<n;i++) wv[i]=x[y[i]];
25 for(i=0;i<m;i++) ws[i]=0;
26 for(i=0;i<n;i++) ws[wv[i]]++;
27 for(i=1;i<m;i++) ws[i]+=ws[i-1];
28 for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];
29 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
30 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
31 }
32 return;
33 }
34
35 int rank[maxn],height[maxn];
36
37 inline void calheight(int *r,int *sa,int n)
38 {
39 int i,j,k=0;
40 for(i=1;i<=n;i++) rank[sa[i]]=i;
41 for(i=0;i<n;height[rank[i++]]=k)
42 for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
43 return;
44 }
45
46 inline void read(int &x)
47 {
48 char ch;
49 while (ch=getchar(),ch > '9' || ch < '0');
50 x=ch-'0';
51 while (ch=getchar(),ch <= '9' && ch >= '0')
52 x=(x<<3)+x+x+ch-'0';
53 }
54
55 inline bool check(int x)
56 {
57 int ans=1;
58 for (int i=1;i<=n;i++)
59 if (height[i] < x)
60 ans=1;
61 else
62 {
63 ans++;
64 if (ans >= k)
65 return 1;
66 }
67 return 0;
68 }
69
70 int main()
71 {
72 read(n);
73 read(k);
74 for (int i=0;i<n;i++)
75 read(a[i]);
76 da(a,sa,n+1,maxn);
77 calheight(a,sa,n);
78 int l=1,r=n;
79 int ans=-1;
80 while (l < r)
81 {
82 int mid=(l+r)>>1;
83 if (check(mid))
84 {
85 ans=mid;
86 l=mid+1;
87 }
88 else
89 r=mid;
90 }
91 printf("%d
",ans);
92 return 0;
93 }
View Code
bzoj1726(已隐藏)
spfa改一下即可
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 5010
5 #define maxm 200010
6
7 struct edge
8 {
9 int to,dist;
10 edge *next;
11 }e[maxm],*head[maxn];
12
13 int ne=0;
14 int min[maxn],sec[maxn],flag[maxn],q[maxn];
15
16 inline void add_edge(int from,int to,int dist)
17 {
18 e[ne].to=to;
19 e[ne].dist=dist;
20 e[ne].next=head[from];
21 head[from]=&e[ne++];
22 }
23
24 inline int _min(int a,int b)
25 {
26 return a < b ? a : b;
27 }
28
29 inline void spfa()
30 {
31 int op=0,cls=1;
32 q[1]=1;
33 memset(min,0x3f,sizeof(min));
34 memset(sec,0x3f,sizeof(sec));
35 min[1]=0;
36 flag[1]=1;
37 while (op != cls)
38 {
39 op++;
40 if (op == maxn)
41 op=0;
42 int x=q[op];
43 flag[x]=0;
44 for (edge *p=head[x];p;p=p->next)
45 {
46 int minl=min[x]+p->dist;
47 int secl=sec[x]+p->dist;
48 if (minl >= sec[p->to])
49 continue;
50 if (minl < min[p->to])
51 {
52 sec[p->to]=_min(min[p->to],secl);
53 min[p->to]=minl;
54 }
55 else
56 {
57 if (minl > min[p->to])
58 sec[p->to]=_min(minl,sec[p->to]);
59 else
60 {
61 if (minl == min[p->to])
62 {
63 sec[p->to]=_min(secl,sec[p->to]);
64 if (sec[p->to] <= secl)
65 continue;
66 }
67 }
68 }
69 if (!flag[p->to])
70 {
71 cls++;
72 if (cls == maxn)
73 cls=0;
74 q[cls]=p->to;
75 flag[p->to]=1;
76 }
77 }
78 }
79 }
80
81 int main()
82 {
83 int n,m;
84 scanf("%d%d",&n,&m);
85 for (int i=1;i<=m;i++)
86 {
87 int x,y,z;
88 scanf("%d%d%d",&x,&y,&z);
89 add_edge(x,y,z);
90 add_edge(y,x,z);
91 }
92 spfa();
93 printf("%d
",sec[n]);
94 return 0;
95 }
View Code
bzoj1797
dinic后在残量网络上求强联通。。。至今还不知道为什么是对的。。。太弱了
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 4010
8 #define maxm 60010
9 #define inf 0x3f3f3f3f
10
11 struct edge
12 {
13 int to,flow,from;
14 edge *next,*part;
15 }e[maxm<<1],*head[maxn];
16
17 int s,t;
18 int ne=0,time=0,cnt=0;
19 int q[maxn],d[maxn];
20 int dfn[maxn],low[maxn],belong[maxn];
21 int sta[maxn],top=0;
22 bool vis[maxn];
23
24 inline void read(int &x)
25 {
26 char ch;
27 while (ch=getchar(),ch > '9' || ch < '0');
28 x=ch-'0';
29 while (ch=getchar(),ch <= '9' && ch >= '0')
30 x=(x<<3)+x+x+ch-'0';
31 }
32
33 inline void add(int from,int to,int flow)
34 {
35 e[ne].to=to;
36 e[ne].from=from;
37 e[ne].flow=flow;
38 e[ne].next=head[from];
39 head[from]=&e[ne++];
40 }
41
42 inline void add_edge(int from,int to,int flow)
43 {
44 e[ne].part=&e[ne+1];
45 e[ne+1].part=&e[ne];
46 add(from,to,flow);
47 add(to,from,0);
48 }
49
50 inline bool bfs()
51 {
52 memset(d,-1,sizeof(d));
53 int op=0,cls=1;
54 q[1]=s;
55 d[s]=0;
56 while (op != cls)
57 {
58 int x=q[++op];
59 for (edge *p=head[x];p;p=p->next)
60 if (p->flow && d[p->to] == -1)
61 {
62 d[p->to]=d[x]+1;
63 q[++cls]=p->to;
64 }
65 }
66 return d[t] != -1;
67 }
68
69 int dfs(int now,int now_flow)
70 {
71 if (now == t)
72 return now_flow;
73 int out=now_flow;
74 for (edge *p=head[now];p;p=p->next)
75 if (p->flow && d[p->to] == d[now]+1 && out)
76 {
77 int f=dfs(p->to,min(p->flow,out));
78 p->flow-=f;
79 p->part->flow+=f;
80 out-=f;
81 }
82 if (now_flow == out)
83 d[now]=-1;
84 return now_flow-out;
85 }
86
87 inline void dinic()
88 {
89 while (bfs())
90 dfs(s,inf);
91 }
92
93 void tarjan(int now)
94 {
95 dfn[now]=low[now]=++time;
96 sta[++top]=now;
97 vis[now]=1;
98 for (edge *p=head[now];p;p=p->next)
99 if (p->flow)
100 {
101 if (!dfn[p->to])
102 {
103 tarjan(p->to);
104 low[now]=min(low[now],low[p->to]);
105 }
106 else
107 if (vis[p->to])
108 low[now]=min(low[now],dfn[p->to]);
109 }
110 if (dfn[now] == low[now])
111 {
112 int v;
113 cnt++;
114 do
115 {
116 v=sta[top--];
117 vis[v]=0;
118 belong[v]=cnt;
119 }
120 while (v != now);
121 }
122 }
123
124 int main()
125 {
126 int n,m;
127 read(n);
128 read(m);
129 read(s);
130 read(t);
131 for (int i=1;i<=m;i++)
132 {
133 int x,y,z;
134 read(x);
135 read(y);
136 read(z);
137 add_edge(x,y,z);
138 }
139 dinic();
140 for (int i=1;i<=n;i++)
141 if (!dfn[i])
142 tarjan(i);
143 for (int i=0;i<ne;i+=2)
144 if (!e[i].flow)
145 {
146 if (belong[e[i].from] == belong[e[i].to])
147 puts("0 0");
148 else
149 if (belong[e[i].from] == belong[s] && belong[e[i].to] == belong[t])
150 puts("1 1");
151 else
152 puts("1 0");
153 }
154 else
155 puts("0 0");
156 return 0;
157 }
View Code
bzoj1798
水水的线段树,乘的标记下放的时候把加的标记一起乘了就可以了
1 #include <cstdio>
2
3 #define maxn 100010
4
5 struct Node
6 {
7 long long sum,lazy_add,lazy_mul;
8 Node()
9 {
10 sum=lazy_add=0;
11 lazy_mul=1;
12 }
13 }t[maxn<<2];
14
15 long long p;
16
17 inline void _pushdown(long long l,long long r,long long rt)
18 {
19 long long mid=(l+r)>>1,add=t[rt].lazy_add,mul=t[rt].lazy_mul;
20 if (t[rt].lazy_mul != 1)
21 {
22 (t[rt<<1].lazy_mul*=mul)%=p;
23 (t[rt<<1|1].lazy_mul*=mul)%=p;
24 (t[rt<<1].lazy_add*=mul)%=p;
25 (t[rt<<1|1].lazy_add*=mul)%=p;
26 (t[rt<<1].sum*=mul)%=p;
27 (t[rt<<1|1].sum*=mul)%=p;
28 t[rt].lazy_mul=1;
29 }
30 if (t[rt].lazy_add)
31 {
32 (t[rt<<1].lazy_add+=add)%=p;
33 (t[rt<<1|1].lazy_add+=add)%=p;
34 (t[rt<<1].sum+=add*(mid-l+1))%=p;
35 (t[rt<<1|1].sum+=add*(r-mid))%=p;
36 t[rt].lazy_add=0;
37 }
38 }
39
40 inline void _update(long long rt)
41 {
42 t[rt].sum=(t[rt<<1].sum+t[rt<<1|1].sum)%p;
43 }
44
45 void add(long long l,long long r,long long rt,long long L,long long R,long long val)
46 {
47 if (l >= L && r <= R)
48 {
49 t[rt].lazy_add+=val;
50 t[rt].sum+=val*(r-l+1);
51 return;
52 }
53 _pushdown(l,r,rt);
54 long long mid=(l+r)>>1;
55 if (L <= mid)
56 add(l,mid,rt<<1,L,R,val);
57 if (R > mid)
58 add(mid+1,r,rt<<1|1,L,R,val);
59 _update(rt);
60 }
61
62 void mul(long long l,long long r,long long rt,long long L,long long R,long long val)
63 {
64 if (l >= L && r <= R)
65 {
66 (t[rt].lazy_add*=val)%=p;
67 (t[rt].lazy_mul*=val)%=p;
68 (t[rt].sum*=val)%=p;
69 return;
70 }
71 _pushdown(l,r,rt);
72 long long mid=(l+r)>>1;
73 if (L <= mid)
74 mul(l,mid,rt<<1,L,R,val);
75 if (R > mid)
76 mul(mid+1,r,rt<<1|1,L,R,val);
77 _update(rt);
78 }
79
80 long long query(long long l,long long r,long long rt,long long L,long long R)
81 {
82 if (l >= L && r <= R)
83 return t[rt].sum;
84 _pushdown(l,r,rt);
85 long long mid=(l+r)>>1,ans=0;
86 if (L <= mid)
87 ans+=query(l,mid,rt<<1,L,R);
88 if (R > mid)
89 ans+=query(mid+1,r,rt<<1|1,L,R);
90 return ans%p;
91 }
92
93 int main()
94 {
95 long long n;
96 scanf("%lld%lld",&n,&p);
97 for (long long i=1;i<=n;i++)
98 {
99 long long x;
100 scanf("%lld",&x);
101 add(1,n,1,i,i,x);
102 }
103 long long _;
104 scanf("%lld",&_);
105 while (_--)
106 {
107 long long x,y,z,w;
108 scanf("%lld%lld%lld",&x,&y,&z);
109 if (x == 1)
110 {
111 scanf("%lld",&w);
112 mul(1,n,1,y,z,w);
113 }
114 if (x == 2)
115 {
116 scanf("%lld",&w);
117 add(1,n,1,y,z,w);
118 }
119 if (x == 3)
120 printf("%lld
",query(1,n,1,y,z));
121 }
122 return 0;
123 }
View Code
bzoj1800
从O(n^4)到O(n)的做法都有,都是0ms。。。看心情吧
1 #include <cstdio>
2
3 #define maxn 25
4
5 int sum[maxn],a[maxn];
6
7 int main()
8 {
9 int n;
10 scanf("%d",&n);
11 int len=0;
12 for (int i=1;i<=n;i++)
13 {
14 scanf("%d",&a[i]);
15 len+=a[i];
16 sum[i]=sum[i-1]+a[i];
17 }
18 int ans=0;
19 for (int i=1;i<n;i++)
20 for (int j=i+1;j<=n;j++)
21 if (sum[j]-sum[i] == len>>1)
22 ans++;
23 printf("%d
",ans*(ans-1)/2);
24 return 0;
25 }
View Code
bzoj1816
二分一下即可
1 #include <cstdio>
2
3 #define maxn 55
4 #define inf 0x3f3f3f3f3f3fLL
5
6 long long n;
7 long long a[maxn];
8
9 inline bool check(long long now,long long rest)
10 {
11 long long del=0;
12 bool flag=1;
13 for (long long i=1;i<=n;i++)
14 if (a[i] < now)
15 {
16 if (now-a[i] <= rest)
17 {
18 rest-=now-a[i];
19 del+=now-a[i];
20 }
21 else
22 {
23 flag=0;
24 break;
25 }
26 }
27 if (!flag)
28 return 0;
29 if (del > now)
30 return 0;
31 return 1;
32 }
33
34 int main()
35 {
36 long long m;
37 scanf("%lld%lld",&n,&m);
38 for (long long i=1;i<=n;i++)
39 scanf("%lld",&a[i]);
40 long long l=-1,r=inf,ans=0;
41 while (l < r)
42 {
43 long long mid=(l+r)>>1;
44 if (check(mid,m))
45 {
46 ans=mid;
47 l=mid+1;
48 }
49 else
50 r=mid;
51 }
52 printf("%lld
",ans);
53 return 0;
54 }
View Code
bzoj1821
贪心+并查集
1 #include <cstdio>
2 #include <cmath>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 1010
8
9 int f[maxn],r[maxn];
10 int x[maxn],y[maxn];
11
12 struct Node
13 {
14 int f,t,dist;
15 }a[maxn*maxn];
16
17 inline bool cmp(const Node a,const Node b)
18 {
19 return a.dist < b.dist;
20 }
21
22 int find(int x)
23 {
24 if (f[x] == x)
25 return x;
26 return f[x]=find(f[x]);
27 }
28
29 inline void _union(int x,int y)
30 {
31 if (r[x] <= r[y])
32 {
33 f[x]=y;
34 r[y]+=r[x];
35 }
36 else
37 {
38 f[y]=x;
39 r[x]+=r[y];
40 }
41 }
42
43 int main()
44 {
45 int n,k;
46 scanf("%d%d",&n,&k);
47 for (int i=1;i<=n;i++)
48 {
49 scanf("%d%d",&x[i],&y[i]);
50 f[i]=i;
51 r[i]=1;
52 }
53 int cnt=n,ne=0;
54 for (int i=1;i<n;i++)
55 for (int j=i+1;j<=n;j++)
56 {
57 ne++;
58 a[ne].f=i;
59 a[ne].t=j;
60 a[ne].dist=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
61 }
62 sort(a+1,a+ne+1,cmp);
63 for (int i=1;i<=ne;i++)
64 {
65 int x=find(a[i].f),y=find(a[i].t);
66 if (x == y)
67 continue;
68 if (cnt == k)
69 {
70 printf("%.2lf
",sqrt(a[i].dist));
71 return 0;
72 }
73 _union(x,y);
74 cnt--;
75 }
76 return 0;
77 }
View Code
bzoj1827
很少的几道奶牛网没有被隐藏的题之一。。。树形DFS(还是不想管这个叫DP)
1 #include <cstdio>
2
3 #define maxn 100010
4
5 struct edge
6 {
7 long long to,dist;
8 edge *next;
9 }e[maxn<<1],*head[maxn];
10
11 long long ne=0;
12 long long ans;
13 long long q[maxn],size[maxn],fa[maxn];
14
15 inline void add_edge(long long from,long long to,long long dist)
16 {
17 e[ne].to=to;
18 e[ne].dist=dist;
19 e[ne].next=head[from];
20 head[from]=&e[ne++];
21 }
22
23 inline void read(long long &x)
24 {
25 x=0;
26 char ch;
27 while (ch=getchar(),ch > '9' || ch < '0');
28 x=ch-'0';
29 while (ch=getchar(),ch <= '9' && ch >= '0')
30 x=(x<<3)+x+x+ch-'0';
31 }
32
33 inline void bfs()
34 {
35 long long op=0,cls=1;
36 q[1]=1;
37 while (op != cls)
38 {
39 long long x=q[++op];
40 for (edge *p=head[x];p;p=p->next)
41 if (p->to != fa[x])
42 {
43 fa[p->to]=x;
44 q[++cls]=p->to;
45 }
46 }
47 }
48
49 inline long long dfs(long long now)
50 {
51 long long ans=0;
52 for (edge *p=head[now];p;p=p->next)
53 if (p->to != fa[now])
54 {
55 ans+=dfs(p->to)+p->dist*size[p->to];
56 size[now]+=size[p->to];
57 }
58 return ans;
59 }
60
61 inline long long dfs(long long now,long long now_ans)
62 {
63 if (now_ans < ans)
64 ans=now_ans;
65 for (edge *p=head[now];p;p=p->next)
66 if (p->to != fa[now])
67 dfs(p->to,now_ans+p->dist*(size[1]-size[p->to]*2));
68 }
69
70 int main()
71 {
72 long long n;
73 read(n);
74 for (long long i=1;i<=n;i++)
75 read(size[i]);
76 for (long long i=1;i<n;i++)
77 {
78 long long x,y,z;
79 read(x);
80 read(y);
81 read(z);
82 add_edge(x,y,z);
83 add_edge(y,x,z);
84 }
85 bfs();
86 long long now=dfs(1);
87 ans=now;
88 dfs(1,now);
89 printf("%lld
",ans);
90 return 0;
91 }
View Code
bzoj1834
dinic后残量网络上加一些边跑费用流
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 2010
8 #define maxm 10010
9 #define inf 0x3f3f3f3f
10
11 struct edge
12 {
13 int to,flow,cost;
14 edge *part,*next;
15 }e[maxm<<1],*head[maxn],*prev[maxn];
16
17 int n,m,k;
18 int ne=0,s,t;
19 int q[maxn],d[maxn];
20 int from[maxm],to[maxm],flow[maxm],cost[maxm];
21 bool flag[maxn];
22
23 inline void add(int from,int to,int flow,int cost)
24 {
25 e[ne].to=to;
26 e[ne].flow=flow;
27 e[ne].cost=cost;
28 e[ne].next=head[from];
29 head[from]=&e[ne++];
30 }
31
32 inline void add_edge(int from,int to,int flow,int cost)
33 {
34 e[ne].part=&e[ne+1];
35 e[ne+1].part=&e[ne];
36 add(from,to,flow,cost);
37 add(to,from,0,-cost);
38 }
39
40 inline bool bfs()
41 {
42 int op=0,cls=1;
43 memset(d,-1,sizeof(d));
44 q[1]=s;
45 d[s]=0;
46 while (op != cls)
47 {
48 int x=q[++op];
49 for (edge *p=head[x];p;p=p->next)
50 if (p->flow && d[p->to] == -1)
51 {
52 q[++cls]=p->to;
53 d[p->to]=d[x]+1;
54 }
55 }
56 return d[t] != -1;
57 }
58
59 int dfs(int now,int now_flow)
60 {
61 if (now == t)
62 return now_flow;
63 int out=now_flow;
64 for (edge *p=head[now];p;p=p->next)
65 if (p->flow && d[p->to] == d[now]+1 && out)
66 {
67 int f=dfs(p->to,min(p->flow,out));
68 p->flow-=f;
69 p->part->flow+=f;
70 out-=f;
71 }
72 if (out == now_flow)
73 d[now]=-1;
74 return now_flow-out;
75 }
76
77 inline int dinic()
78 {
79 int ans=0;
80 while (bfs())
81 ans+=dfs(s,inf);
82 return ans;
83 }
84
85 inline bool spfa()
86 {
87 int op=0,cls=1;
88 memset(flag,0,sizeof(flag));
89 memset(d,0x3f,sizeof(d));
90 flag[s]=1;
91 d[s]=0;
92 q[1]=s;
93 while (op != cls)
94 {
95 op++;
96 if (op == maxn)
97 op=0;
98 int x=q[op];
99 flag[x]=0;
100 for (edge *p=head[x];p;p=p->next)
101 if (p->flow && d[x]+p->cost < d[p->to])
102 {
103 d[p->to]=d[x]+p->cost;
104 prev[p->to]=p->part;
105 if (!flag[p->to])
106 {
107 cls++;
108 if (cls == maxn)
109 cls=0;
110 q[cls]=p->to;
111 flag[p->to]=1;
112 }
113 }
114 }
115 return d[t] != inf;
116 }
117
118 inline int agument()
119 {
120 int f=inf,ans=0;
121 for (edge *p=prev[t];p;p=prev[p->to])
122 f=min(f,p->part->flow);
123 for (edge *p=prev[t];p;p=prev[p->to])
124 {
125 p->flow+=f;
126 p->part->flow-=f;
127 ans+=p->part->cost*f;
128 }
129 return ans;
130 }
131
132 inline int min_cost()
133 {
134 int ans=0;
135 while (spfa())
136 ans+=agument();
137 return ans;
138 }
139
140 int main()
141 {
142 scanf("%d%d%d",&n,&m,&k);
143 for (int i=1;i<=m;i++)
144 {
145 scanf("%d%d%d%d",&from[i],&to[i],&flow[i],&cost[i]);
146 add_edge(from[i],to[i],flow[i],0);
147 }
148 s=1;
149 t=n;
150 printf("%d ",dinic());
151 for (int i=1;i<=m;i++)
152 add_edge(from[i],to[i],inf,cost[i]);
153 s=0;
154 add_edge(0,1,k,0);
155 printf("%d
",min_cost());
156 return 0;
157 }
View Code
bzoj1854
枚举加边网络流T掉之后就写了个并查集过了。。。
1 #include <cstdio>
2
3 #define maxn 10010
4
5 int f[maxn],edge[maxn];
6 int n;
7
8 int find(int x)
9 {
10 if (f[x] == x)
11 return x;
12 return f[x]=find(f[x]);
13 }
14
15 inline void _union(int a,int b)
16 {
17 int x=find(a);
18 int y=find(b);
19 if (x > y)
20 {
21 int t;
22 t=x,x=y,y=t;
23 }
24 if (x == y)
25 edge[x]++;
26 else
27 {
28 edge[x]+=edge[y]+1;
29 f[y]=x;
30 }
31 }
32
33 int main()
34 {
35 //freopen("1.in","r",stdin);
36 //freopen("1.out","w",stdout);
37 scanf("%d",&n);
38 for (int i=1;i<=maxn;i++)
39 f[i]=i;
40 for (int i=1;i<=n;i++)
41 {
42 int x,y;
43 scanf("%d%d",&x,&y);
44 _union(x,y);
45 }
46 for (int i=1;i<=maxn;i++)
47 {
48 if (edge[find(i)])
49 edge[find(i)]--;
50 else
51 {
52 printf("%d
",i-1);
53 break;
54 }
55 }
56 return 0;
57 }
View Code
bzoj1855
单调队列优化的DP
1 #include <cstdio>
2
3 #define maxn 2010
4 #define inf 0x3f3f3f3f
5
6 int t,maxp,w;
7 int f[maxn][maxn],as[maxn],ap[maxn],bs[maxn],bp[maxn];
8 int q1[maxn],q2[maxn],pos[maxn];
9
10 inline int max(int a,int b)
11 {
12 return a > b ? a : b;
13 }
14
15 int main()
16 {
17 scanf("%d%d%d",&t,&maxp,&w);
18 for (int i=1;i<=t;i++)
19 scanf("%d%d%d%d",&ap[i],&bp[i],&as[i],&bs[i]);
20 for (int i=1;i<=w+1;i++)
21 for (int j=1;j<=maxp;j++)
22 f[i][j]=-inf;
23 for (int i=w+2;i<=t;i++)
24 {
25 for (int j=0;j<=maxp;j++)
26 {
27 f[i][j]=f[i-1][j];
28 q1[j]=f[i-w-1][j]+ap[i-w-1]*j;
29 q2[j]=f[i-w-1][j]+bp[i-w-1]*j;
30 }
31 int op,cls;
32 op=cls=1;
33 pos[1]=0;
34 for (int j=1;j<=maxp;j++)
35 {
36 if (pos[op] < j-as[i-w-1])
37 op++;
38 f[i][j]=max(f[i][j],q1[pos[op]]-ap[i-w-1]*j);
39 while (op <= cls && q1[j] > q1[pos[cls]])
40 cls--;
41 pos[++cls]=j;
42 }
43 op=cls=1;
44 pos[1]=maxp;
45 for (int j=maxp-1;j>=0;j--)
46 {
47 if (pos[op] > j+bs[i-w-1])
48 op++;
49 f[i][j]=max(f[i][j],q2[pos[op]]-bp[i-w-1]*j);
50 while (op <= cls && q2[j] > q2[pos[cls]])
51 cls--;
52 pos[++cls]=j;
53 }
54 }
55 int ans=0;
56 for (int i=1;i<=t;i++)
57 for (int j=0;j<=maxp;j++)
58 {
59 if (j <= bs[i])
60 ans=max(ans,f[i][j]+bp[i]*j);
61 else
62 ans=max(ans,f[i][j]+bp[i]*bs[i]);
63 }
64 printf("%d
",ans);
65 return 0;
66 }
View Code
bzoj1858
比较难写的线段树,加了个读入优化就rank1了。。。(已被艹)
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 100010
7
8 struct Node
9 {
10 int sum,lmax,rmax,max,lmin,rmin,min,lazy;
11 }t[maxn<<2];
12
13 inline void read(int &x)
14 {
15 char ch;
16 while (ch=getchar(),ch > '9' || ch < '0');
17 x=ch-'0';
18 while (ch=getchar(),ch <= '9' && ch >= '0')
19 x=(x<<3)+x+x+ch-'0';
20 }
21
22 inline void _pushdown(int l,int r,int rt)
23 {
24 if (t[rt].lazy == -1)
25 return;
26 int mid=(l+r)>>1;
27 if (t[rt].lazy == 0)
28 {
29 t[rt].lazy=-1;
30 t[rt<<1].lazy=t[rt<<1|1].lazy=0;
31 t[rt<<1].lmin=t[rt<<1].rmin=t[rt<<1].min=mid-l+1;
32 t[rt<<1|1].lmin=t[rt<<1|1].rmin=t[rt<<1|1].min=r-mid;
33 t[rt<<1].lmax=t[rt<<1].rmax=t[rt<<1].max=t[rt<<1|1].lmax=t[rt<<1|1].rmax=t[rt<<1|1].max=0;
34 t[rt<<1].sum=t[rt<<1|1].sum=0;
35 return;
36 }
37 if (t[rt].lazy == 1)
38 {
39 t[rt].lazy=-1;
40 t[rt<<1].lazy=t[rt<<1|1].lazy=1;
41 t[rt<<1].lmax=t[rt<<1].rmax=t[rt<<1].max=mid-l+1;
42 t[rt<<1|1].lmax=t[rt<<1|1].rmax=t[rt<<1|1].max=r-mid;
43 t[rt<<1].lmin=t[rt<<1].rmin=t[rt<<1].min=t[rt<<1|1].lmin=t[rt<<1|1].rmin=t[rt<<1|1].min=0;
44 t[rt<<1].sum=mid-l+1;
45 t[rt<<1|1].sum=r-mid;
46 return;
47 }
48 if (t[rt].lazy == 2)
49 {
50 t[rt].lazy=-1;
51 t[rt<<1].lazy=1-t[rt<<1].lazy;
52 t[rt<<1|1].lazy=1-t[rt<<1|1].lazy;
53 swap(t[rt<<1].lmax,t[rt<<1].lmin);
54 swap(t[rt<<1].rmax,t[rt<<1].rmin);
55 swap(t[rt<<1].max,t[rt<<1].min);
56 swap(t[rt<<1|1].lmax,t[rt<<1|1].lmin);
57 swap(t[rt<<1|1].rmax,t[rt<<1|1].rmin);
58 swap(t[rt<<1|1].max,t[rt<<1|1].min);
59 t[rt<<1].sum=mid-l+1-t[rt<<1].sum;
60 t[rt<<1|1].sum=r-mid-t[rt<<1|1].sum;
61 }
62 }
63
64 inline void _update(int l,int r,int rt)
65 {
66 int mid=(l+r)>>1;
67 t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;
68 if (t[rt<<1].sum == mid-l+1)
69 t[rt].lmax=mid-l+1+t[rt<<1|1].lmax;
70 else
71 t[rt].lmax=t[rt<<1].lmax;
72 if (!t[rt<<1].sum)
73 t[rt].lmin=mid-l+1+t[rt<<1|1].lmin;
74 else
75 t[rt].lmin=t[rt<<1].lmin;
76 if (t[rt<<1|1].sum == r-mid)
77 t[rt].rmax=r-mid+t[rt<<1].rmax;
78 else
79 t[rt].rmax=t[rt<<1|1].rmax;
80 if (!t[rt<<1|1].sum)
81 t[rt].rmin=r-mid+t[rt<<1].rmin;
82 else
83 t[rt].rmin=t[rt<<1|1].rmin;
84 t[rt].max=max(max(t[rt<<1].max,t[rt<<1|1].max),t[rt<<1].rmax+t[rt<<1|1].lmax);
85 t[rt].min=max(max(t[rt<<1].min,t[rt<<1|1].min),t[rt<<1].rmin+t[rt<<1|1].lmin);
86 }
87
88 void build(int l,int r,int rt)
89 {
90 t[rt].lazy=-1;
91 if (l == r)
92 {
93 read(t[rt].sum);
94 if (t[rt].sum)
95 t[rt].lmax=t[rt].rmax=t[rt].max=1;
96 else
97 t[rt].lmin=t[rt].rmin=t[rt].min=1;
98 return;
99 }
100 int mid=(l+r)>>1;
101 build(l,mid,rt<<1);
102 build(mid+1,r,rt<<1|1);
103 _update(l,r,rt);
104 }
105
106 void insert(int l,int r,int rt,int L,int R,int add)
107 {
108 if (l >= L && r <= R)
109 {
110 if (add == 2)
111 t[rt].lazy=1-t[rt].lazy;
112 else
113 t[rt].lazy=add;
114 if (add == 0)
115 {
116 t[rt].max=t[rt].lmax=t[rt].rmax=t[rt].sum=0;
117 t[rt].min=t[rt].lmin=t[rt].rmin=r-l+1;
118 }
119 if (add == 1)
120 {
121 t[rt].max=t[rt].lmax=t[rt].rmax=t[rt].sum=r-l+1;
122 t[rt].min=t[rt].lmin=t[rt].rmin=0;
123 }
124 if (add == 2)
125 {
126 t[rt].sum=r-l+1-t[rt].sum;
127 swap(t[rt].max,t[rt].min);
128 swap(t[rt].lmax,t[rt].lmin);
129 swap(t[rt].rmax,t[rt].rmin);
130 }
131 return;
132 }
133 _pushdown(l,r,rt);
134 int mid=(l+r)>>1;
135 if (L <= mid)
136 insert(l,mid,rt<<1,L,R,add);
137 if (R > mid)
138 insert(mid+1,r,rt<<1|1,L,R,add);
139 _update(l,r,rt);
140 }
141
142 int query(int l,int r,int rt,int L,int R)
143 {
144 if (l != r)
145 _pushdown(l,r,rt);
146 if (l == L && r == R)
147 return t[rt].sum;
148 int mid=(l+r)>>1;
149 if (R <= mid)
150 return query(l,mid,rt<<1,L,R);
151 else
152 if (L > mid)
153 return query(mid+1,r,rt<<1|1,L,R);
154 else
155 return query(l,mid,rt<<1,L,mid)+query(mid+1,r,rt<<1|1,mid+1,R);
156 }
157
158 int query_l(int l,int r,int rt,int L,int R)
159 {
160 if (l != r)
161 _pushdown(l,r,rt);
162 if (l == L && r == R)
163 return t[rt].lmax;
164 if (t[rt].sum == r-l+1)
165 return R-L+1;
166 if (!t[rt].sum)
167 return 0;
168 int mid=(l+r)>>1;
169 if (R <= mid)
170 return query_l(l,mid,rt<<1,L,R);
171 if (t[rt<<1].sum == mid-l+1)
172 return mid-l+1+query_l(mid+1,r,rt<<1|1,mid+1,R);
173 return query_l(l,mid,rt<<1,L,mid);
174 }
175
176 int query_r(int l,int r,int rt,int L,int R)
177 {
178 if (l != r)
179 _pushdown(l,r,rt);
180 if (l == L && r == R)
181 return t[rt].rmax;
182 if (t[rt].sum == r-l+1)
183 return R-L+1;
184 if (!t[rt].sum)
185 return 0;
186 int mid=(l+r)>>1;
187 if (L > mid)
188 return query_r(mid+1,r,rt<<1|1,L,R);
189 if (t[rt<<1|1].sum == r-mid)
190 return r-mid+query_r(l,mid,rt<<1,L,mid);
191 return query_r(mid+1,r,rt<<1|1,mid+1,R);
192 }
193
194 int query_all(int l,int r,int rt,int L,int R)
195 {
196 if (l != r)
197 _pushdown(l,r,rt);
198 if (l == L && r == R)
199 return t[rt].max;
200 if (t[rt].sum == r-l+1)
201 return R-L+1;
202 if (!t[rt].sum)
203 return 0;
204 int mid=(l+r)>>1;
205 if (L > mid)
206 return query_all(mid+1,r,rt<<1|1,L,R);
207 else
208 if (R <= mid)
209 return query_all(l,mid,rt<<1,L,R);
210 else
211 return max(max(query_all(l,mid,rt<<1,L,mid),query_all(mid+1,r,rt<<1|1,mid+1,R)),query_r(l,mid,rt<<1,L,mid)+query_l(mid+1,r,rt<<1|1,mid+1,R));
212 }
213
214 int main()
215 {
216 int n,m;
217 read(n);
218 read(m);
219 build(1,n,1);
220 while (m--)
221 {
222 int x,y,z;
223 read(x);
224 read(y);
225 read(z);
226 y++;
227 z++;
228 if (x == 0)
229 insert(1,n,1,y,z,0);
230 if (x == 1)
231 insert(1,n,1,y,z,1);
232 if (x == 2)
233 insert(1,n,1,y,z,2);
234 if (x == 3)
235 printf("%d
",query(1,n,1,y,z));
236 if (x == 4)
237 printf("%d
",query_all(1,n,1,y,z));
238 }
239 return 0;
240 }
View Code
bzoj1861
比较蛋疼的splay
1 #include <cstdio>
2
3 #define maxn 80010
4
5 int n;
6 int a[maxn];
7
8 struct Node
9 {
10 int size,num;
11 Node *s[2],*par;
12 };
13
14 struct splay
15 {
16 Node t[maxn],null;
17 Node *root,*pos[maxn];
18 int ne;
19
20 splay()
21 {
22 null.s[0]=null.s[1]=null.par=&null;
23 null.size=0;
24 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2;t[0].num=0;
25 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1;t[1].num=0;
26 ne=1;
27 root=&t[0];
28 }
29
30 inline void _update(Node* now)
31 {
32 if (now == &null)
33 return;
34 now->size=now->s[0]->size+now->s[1]->size+1;
35 }
36
37 inline void _rot(Node* now,int l)
38 {
39 int r=!l;
40 Node* p=now->par;
41 Node* s=now->s[l];
42 (now->s[l]=s->s[r])->par=now;
43 (s->s[r]=now)->par=s;
44 s->par=p;
45 if (p != &null)
46 p->s[now == p->s[1]]=s;
47 _update(now);
48 _update(s);
49 }
50
51 inline void _splay(Node* now,Node* goal)
52 {
53 while (now->par != goal)
54 {
55 Node* p=now->par;
56 Node* g=p->par;
57 bool dp=now == p->s[1];
58 bool dg=p == g->s[1];
59 if (g == goal)
60 {
61 _rot(p,dp);
62 break;
63 }
64 if (dp == dg)
65 {
66 _rot(g,dg);
67 _rot(p,dp);
68 }
69 else
70 {
71 _rot(p,dp);
72 _rot(g,dg);
73 }
74 }
75 if (goal == &null)
76 root=now;
77 }
78
79 inline Node* _select(int v)
80 {
81 Node* now=root;
82 while (1)
83 {
84 if (now == &null)
85 return now;
86 if (now->s[0]->size+1 == v)
87 return now;
88 if (v <= now->s[0]->size)
89 now=now->s[0];
90 else
91 {
92 v-=now->s[0]->size+1;
93 now=now->s[1];
94 }
95 }
96 }
97
98 inline void build(int n)
99 {
100 ne++;
101 t[1].s[0]=&t[ne];
102 t[ne].s[0]=&null;
103 t[ne].s[1]=&t[ne+1];
104 t[ne].num=a[1];
105 t[ne].size=n;
106 t[ne].par=&t[1];
107 pos[a[1]]=&t[ne];
108 for (int i=2;i<n;i++)
109 {
110 ne++;
111 t[ne].size=n-i+1;
112 t[ne].s[0]=&null;
113 t[ne].par=&t[ne-1];
114 t[ne].s[1]=&t[ne+1];
115 t[ne].num=a[i];
116 pos[a[i]]=&t[ne];
117 }
118 ne++;
119 t[ne].s[0]=t[ne].s[1]=&null;
120 t[ne].par=&t[ne-1];
121 t[ne].num=a[n];
122 t[ne].size=1;
123 pos[a[n]]=&t[ne];
124 _update(root->s[1]);
125 _update(root);
126 }
127
128 inline void top(int s)
129 {
130 Node* now=pos[s];
131 _splay(now,&null);
132 int r=now->s[0]->size+1;
133 Node* p=_select(r-1);
134 Node* q=_select(r+1);
135 _splay(p,&null);
136 _splay(q,root);
137 q->s[0]=&null;
138 q->size--;
139 p->size--;
140 p=_select(2);
141 _splay(p,&null);
142 (p->s[0]->s[1]=now)->par=p->s[0];
143 now->s[0]=now->s[1]=&null;
144 p->s[0]->size++;
145 p->size++;
146 }
147
148 inline void bottom(int s)
149 {
150 Node* now=pos[s];
151 _splay(now,&null);
152 int r=now->s[0]->size+1;
153 Node* p=_select(r-1);
154 Node* q=_select(r+1);
155 _splay(p,&null);
156 _splay(q,root);
157 q->s[0]=&null;
158 q->size--;
159 p->size--;
160 p=_select(n);
161 _splay(p,&null);
162 (p->s[1]->s[0]=now)->par=p->s[1];
163 now->s[0]=now->s[1]=&null;
164 p->s[1]->size++;
165 p->size++;
166 }
167
168 inline void insert(int s,int t)
169 {
170 if (!t)
171 return;
172 Node* now=pos[s];
173 _splay(now,&null);
174 int r=now->s[0]->size+1;
175 Node* p=_select(r-1);
176 Node* q=_select(r+1);
177 _splay(p,&null);
178 _splay(q,root);
179 q->s[0]=&null;
180 q->size--;
181 p->size--;
182 if (t == 1)
183 {
184 p=_select(r);
185 q=_select(r+1);
186 _splay(p,&null);
187 _splay(q,root);
188 (q->s[0]=now)->par=q;
189 now->s[0]=now->s[1]=&null;
190 q->size++;
191 p->size++;
192 }
193 else
194 {
195 p=_select(r-2);
196 q=_select(r-1);
197 _splay(p,&null);
198 _splay(q,root);
199 (q->s[0]=now)->par=q;
200 now->s[0]=now->s[1]=&null;
201 q->size++;
202 p->size++;
203 }
204 }
205
206 inline int ask(int s)
207 {
208 Node* now=pos[s];
209 _splay(now,&null);
210 return now->s[0]->size-1;
211 }
212
213 inline int query(int v)
214 {
215 Node* now=_select(v+1);
216 return now->num;
217 }
218
219 void travel(Node* now)
220 {
221 if (now->s[0] != &null)
222 travel(now->s[0]);
223 printf("%d ",now->num);
224 if (now->s[1] != &null)
225 travel(now->s[1]);
226 }
227 }t;
228
229 int main()
230 {
231 int m;
232 scanf("%d%d",&n,&m);
233 for (int i=1;i<=n;i++)
234 scanf("%d",&a[i]);
235 t.build(n);
236 while (m--)
237 {
238 char ch[10];
239 int x,y;
240 scanf("%s%d",ch,&x);
241 if (ch[0] == 'T')
242 t.top(x);
243 if (ch[0] == 'B')
244 t.bottom(x);
245 if (ch[0] == 'I')
246 {
247 scanf("%d",&y);
248 t.insert(x,y);
249 }
250 if (ch[0] == 'A')
251 printf("%d
",t.ask(x));
252 if (ch[0] == 'Q')
253 printf("%d
",t.query(x));
254 }
255 return 0;
256 }
View Code
bzoj1876
python水掉
1 def gcd(a, b):
2 while b!=0 :
3 if a % b == 0:
4 return b
5 else:
6 c=a%b
7 a=b
8 b=c
9 x = int(raw_input())
10 y = int(raw_input())
11 print(gcd(x,y))
View Code
bzoj1877
经典的拆点费用流
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 1010
8 #define maxm 200010
9 #define inf 0x3f3f3f3f
10
11 struct edge
12 {
13 int to,flow,cost;
14 edge *next,*part;
15 }e[maxm],*head[maxn],*prev[maxn];
16
17 int s,t;
18 int ne=0;
19 int q[maxn],d[maxn];
20 bool flag[maxn];
21 int flow=0;
22
23 inline void add(int from,int to,int flow,int cost)
24 {
25 e[ne].to=to;
26 e[ne].flow=flow;
27 e[ne].cost=cost;
28 e[ne].next=head[from];
29 head[from]=&e[ne++];
30 }
31
32 inline void add_edge(int from,int to,int flow,int cost)
33 {
34 e[ne].part=&e[ne+1];
35 e[ne+1].part=&e[ne];
36 add(from,to,flow,cost);
37 add(to,from,0,-cost);
38 }
39
40 inline bool spfa()
41 {
42 memset(d,0x3f,sizeof(d));
43 memset(flag,0,sizeof(flag));
44 int op=0,cls=1;
45 q[1]=s;
46 d[s]=0;
47 flag[s]=1;
48 while (op != cls)
49 {
50 op=op == maxn-1 ? 0 : op+1;
51 int x=q[op];
52 for (edge *p=head[x];p;p=p->next)
53 if (p->flow && d[p->to] > d[x]+p->cost)
54 {
55 d[p->to]=d[x]+p->cost;
56 prev[p->to]=p->part;
57 if (!flag[p->to])
58 {
59 if (op != cls)
60 {
61 int now=op == maxn-1 ? 0 : op+1;
62 if (d[p->to] < d[q[now]])
63 {
64 q[op]=p->to;
65 op=op == 0 ? maxn-1 : op-1;
66 }
67 else
68 {
69 cls=cls == maxn-1 ? 0 : cls+1;
70 q[cls]=p->to;
71 }
72 }
73 else
74 {
75 cls=cls == maxn-1 ? 0 : cls+1;
76 q[cls]=p->to;
77 }
78 flag[p->to]=1;
79 }
80 }
81 flag[x]=0;
82 }
83 return d[t] != inf;
84 }
85
86 inline int agument()
87 {
88 int f=inf,ans=0;
89 for (edge *p=prev[t];p;p=prev[p->to])
90 f=min(f,p->part->flow);
91 flow+=f;
92 for (edge *p=prev[t];p;p=prev[p->to])
93 {
94 p->flow+=f;
95 p->part->flow-=f;
96 ans+=p->part->cost*f;
97 }
98 return ans;
99 }
100
101 inline int min_cost()
102 {
103 int ans=0;
104 while (spfa())
105 ans+=agument();
106 return ans;
107 }
108
109 int l[maxn],r[maxn];
110
111 int main()
112 {
113 int n,m;
114 scanf("%d%d",&n,&m);
115 s=1,t=2;
116 l[1]=1;
117 r[n]=2;
118 int cnt=2;
119 for (int i=2;i<n;i++)
120 {
121 r[i]=++cnt;
122 l[i]=++cnt;
123 }
124 for (int i=1;i<=m;i++)
125 {
126 int x,y,z;
127 scanf("%d%d%d",&x,&y,&z);
128 if (x == n || y == 1)
129 continue;
130 add_edge(l[x],r[y],1,z);
131 }
132 for (int i=2;i<n;i++)
133 add_edge(r[i],l[i],1,0);
134 int ans=min_cost();
135 printf("%d %d
",flow,ans);
136 return 0;
137 }
View Code
bzoj1878
离线树状数组,其实可以在线主席树,但是懒得写了
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 50010
7 #define maxm 200010
8
9 struct query
10 {
11 int l,r,id;
12 inline bool operator < (const query b) const
13 {
14 return l < b.l;
15 }
16 }q[maxm];
17
18 int n;
19 int a[maxn],b[maxn];
20 int bit[maxn];
21 int now[maxn],next[maxn];
22 int ans[maxm];
23 char s[10];
24
25 inline void read(int &x)
26 {
27 x=0;
28 char ch;
29 while (ch=getchar(),ch > '9' || ch < '0');
30 x=ch-'0';
31 while (ch=getchar(),ch <= '9' && ch >= '0')
32 x=(x<<3)+x+x+ch-'0';
33 }
34
35 inline void bit_update(int now,int add)
36 {
37 for (;now<=n;now+=now&-now)
38 bit[now]+=add;
39 }
40
41 inline int query(int now)
42 {
43 int ans=0;
44 for (;now;now-=now&-now)
45 ans+=bit[now];
46 return ans;
47 }
48
49 inline void writeln(int x)
50 {
51 int cnt=0;
52 while (x)
53 {
54 s[++cnt]=(x%10)+'0';
55 x/=10;
56 }
57 for (int i=cnt;i;i--)
58 putchar(s[i]);
59 puts("");
60 }
61
62 int main()
63 {
64 read(n);
65 for (int i=1;i<=n;i++)
66 {
67 read(a[i]);
68 b[i]=a[i];
69 }
70 sort(b+1,b+n+1);
71 int size=unique(b+1,b+n+1)-b-1;
72 for (int i=1;i<=n;i++)
73 a[i]=lower_bound(b+1,b+size+1,a[i])-b;
74 for (int i=1;i<=size;i++)
75 now[i]=n+1;
76 for (int i=n;i;i--)
77 {
78 next[i]=now[a[i]];
79 now[a[i]]=i;
80 }
81 for (int i=1;i<=size;i++)
82 bit_update(now[i],1);
83 int m;
84 read(m);
85 for (int i=1;i<=m;i++)
86 {
87 read(q[i].l);
88 read(q[i].r);
89 q[i].id=i;
90 }
91 sort(q+1,q+m+1);
92 int nowl=1;
93 for (int i=1;i<=m;i++)
94 {
95 while (nowl < q[i].l)
96 {
97 bit_update(nowl,-1);
98 bit_update(next[nowl],1);
99 nowl++;
100 }
101 ans[q[i].id]=query(q[i].r);
102 }
103 for (int i=1;i<=m;i++)
104 writeln(ans[i]);
105 return 0;
106 }
View Code
bzoj1901
树状数组套主席树模板题
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 const int maxn=100010;
7 const int maxm=3000010;
8
9 struct Node
10 {
11 Node* s[2];
12 int size;
13 Node()
14 {
15 size=0;
16 }
17 }t[maxm],*root[maxn],*L[30],*R[30],null;
18
19 int ne=0,size,n,m;
20 int lsize,rsize;
21 int a[maxn],b[maxn];
22 int p[maxn],q[maxn],k[maxn];
23 char ch[maxn][3];
24
25 Node* build(int val,int l,int r)
26 {
27 Node* now=&t[ne++];
28 now->s[0]=now->s[1]=&null;
29 now->size=1;
30 if (l == r)
31 return now;
32 int mid=(l+r)>>1;
33 if (val <= mid)
34 now->s[0]=build(val,l,mid);
35 else
36 now->s[1]=build(val,mid+1,r);
37 return now;
38 }
39
40 void update(Node* now,int val,int l,int r,int flag)
41 {
42 while (1)
43 {
44 now->size+=flag;
45 if (l == r)
46 break;
47 int mid=(l+r)>>1;
48 if (val <= mid)
49 {
50 if (now->s[0] == &null)
51 {
52 now->s[0]=build(val,l,mid);
53 return;
54 }
55 else
56 {
57 now=now->s[0];
58 r=mid;
59 }
60 }
61 else
62 {
63 if (now->s[1] == &null)
64 {
65 now->s[1]=build(val,mid+1,r);
66 return;
67 }
68 else
69 {
70 now=now->s[1];
71 l=mid+1;
72 }
73 }
74 }
75 }
76
77 void bit_update(int now,int val,int flag)
78 {
79 for (;now <= n;now+=now & -now)
80 {
81 if (root[now] == &null)
82 root[now]=build(val,1,size);
83 else
84 update(root[now],val,1,size,flag);
85 }
86 }
87
88 int query(int l,int r,int k)
89 {
90 if (l == r)
91 return l;
92 int lsum=0,rsum=0,del,mid=(l+r)>>1;
93 for (int i=1;i<=lsize;i++)
94 lsum+=L[i]->s[0]->size;
95 for (int i=1;i<=rsize;i++)
96 rsum+=R[i]->s[0]->size;
97 del=rsum-lsum;
98 if (k <= del)
99 {
100 for (int i=1;i <= lsize;i++)
101 L[i]=L[i]->s[0];
102 for (int i=1;i <= rsize;i++)
103 R[i]=R[i]->s[0];
104 return query(l,mid,k);
105 }
106 else
107 {
108 for (int i=1;i <= lsize;i++)
109 L[i]=L[i]->s[1];
110 for (int i=1;i <= rsize;i++)
111 R[i]=R[i]->s[1];
112 return query(mid+1,r,k-del);
113 }
114 }
115
116 int ask(int l,int r,int k)
117 {
118 lsize=rsize=0;
119 if (!l)
120 L[++lsize]=&null;
121 else
122 for (;l > 0;l-=l & -l)
123 L[++lsize]=root[l];
124 for (;r > 0;r-=r & -r)
125 R[++rsize]=root[r];
126 return query(1,size,k);
127 }
128
129 int main()
130 {
131 null.s[0]=null.s[1]=&null;
132 scanf("%d%d",&n,&m);
133 for (int i=1;i <= n;i++)
134 {
135 scanf("%d",&a[i]);
136 b[i]=a[i];
137 }
138 size=n;
139 for (int i=1;i <= m;i++)
140 {
141 scanf("%s%d%d",ch[i],&p[i],&q[i]);
142 if (ch[i][0] == 'Q')
143 scanf("%d",&k[i]);
144 else
145 b[++size]=q[i];
146 }
147 sort(b+1,b+size+1);
148 size=unique(b+1,b+size+1)-b-1;
149 for (int i=1;i <= n;i++)
150 a[i]=lower_bound(b+1,b+size+1,a[i])-b;
151 for (int i=1;i <= n;i++)
152 root[i]=&null;
153 for (int i=1;i <= n;i++)
154 bit_update(i,a[i],1);
155 for (int i=1;i <= m;i++)
156 {
157 if (ch[i][0] == 'Q')
158 printf("%d
",b[ask(p[i]-1,q[i],k[i])]);
159 else
160 {
161 int pos=lower_bound(b+1,b+size+1,q[i])-b;
162 bit_update(p[i],a[p[i]],-1);
163 a[p[i]]=pos;
164 bit_update(p[i],a[p[i]],1);
165 }
166 }
167 return 0;
168 }
View Code
bzoj1911
斜率优化的DP
1 #include <cstdio>
2
3 #define maxn 1000010
4
5 #ifdef unix
6 #define LL "%lld"
7 #else
8 #define LL "%I64d"
9 #endif
10
11 inline long long sqr(long long x)
12 {
13 return x*x;
14 }
15
16 long long n,a,b,c;
17 long long sum[maxn],dp[maxn],q[maxn];
18
19 inline long long calc(long long x,long long y)
20 {
21 return dp[x]+a*sqr(sum[x])-b*sum[x]-dp[y]-a*sqr(sum[y])+b*sum[y];
22 }
23
24 inline void read(int &x)
25 {
26 char ch;
27 while (ch=getchar(),ch > '9' || ch < '0');
28 x=ch-'0';
29 while (ch=getchar(),ch <= '9' && ch >= '0')
30 x=(x<<3)+x+x+ch-'0';
31 }
32
33 int main()
34 {
35 scanf(LL LL LL LL,&n,&a,&b,&c);
36 for (int i=1;i<=n;i++)
37 {
38 int x;
39 read(x);
40 sum[i]=sum[i-1]+x;
41 }
42 int op=0,cls=0;
43 for (int i=1;i<=n;i++)
44 {
45 while (op < cls)
46 {
47 if (calc(q[op+1],q[op]) >= 2*a*sum[i]*(sum[q[op+1]]-sum[q[op]]))
48 op++;
49 else
50 break;
51 }
52 dp[i]=dp[q[op]]+a*sqr(sum[i]-sum[q[op]])+b*(sum[i]-sum[q[op]])+c;
53 while (op < cls)
54 {
55 if (calc(q[cls],q[cls-1])*(sum[i]-sum[q[cls]]) <= calc(i,q[cls])*(sum[q[cls]]-sum[q[cls-1]]))
56 cls--;
57 else
58 break;
59 }
60 q[++cls]=i;
61 }
62 printf(LL,dp[n]);
63 return 0;
64 }
View Code
bzoj1912
对于K=1,两次DFS找直径即可,对于K=2,在做完第一步之后把经过的边边权赋为-1,再找一次最长链即可
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 100010
5 #define inf 0x3f3f3f3f
6
7 struct edge
8 {
9 int to,dist;
10 edge *next,*part;
11 }e[maxn<<1],*head[maxn],*prev[maxn];
12
13 int ne=0,n;
14 int q[maxn],d[maxn],fa[maxn];
15 int max[maxn],sec[maxn];
16 bool flag[maxn];
17
18 inline int min(int a,int b)
19 {
20 return a < b ? a : b;
21 }
22
23 inline void add(int from,int to,int dist)
24 {
25 e[ne].to=to;
26 e[ne].dist=dist;
27 e[ne].next=head[from];
28 head[from]=&e[ne++];
29 }
30
31 inline void add_edge(int from,int to,int dist)
32 {
33 e[ne].part=&e[ne+1];
34 e[ne+1].part=&e[ne];
35 add(from,to,dist);
36 add(to,from,dist);
37 }
38
39 inline int bfs(int s)
40 {
41 int op=0,cls=1;
42 memset(d,0,sizeof(d));
43 memset(flag,0,sizeof(flag));
44 q[1]=s;
45 flag[s]=1;
46 while (op != cls)
47 {
48 int x=q[++op];
49 flag[x]=1;
50 for (edge *p=head[x];p;p=p->next)
51 if (!flag[p->to])
52 {
53 d[p->to]=d[x]+p->dist;
54 prev[p->to]=p->part;
55 fa[p->to]=x;
56 q[++cls]=p->to;
57 }
58 }
59 int _max=0,now=s;
60 for (int i=1;i<=n;i++)
61 if (d[i] > _max)
62 {
63 _max=d[i];
64 now=i;
65 }
66 return now;
67 }
68
69 int main()
70 {
71 int k;
72 int x,y;
73 scanf("%d%d",&n,&k);
74 for (int i=1;i<n;i++)
75 {
76 scanf("%d%d",&x,&y);
77 add_edge(x,y,1);
78 }
79 x=bfs(1);
80 memset(prev,0x0,sizeof(prev));
81 y=bfs(x);
82 prev[x]=NULL;
83 int ans=(n-1)*2-d[y]+1;
84 if (k == 1)
85 {
86 printf("%d
",ans);
87 return 0;
88 }
89 for (edge *p=prev[y];p;p=prev[p->to])
90 p->dist=p->part->dist=-1;
91 for (int i=1;i<=n;i++)
92 max[i]=sec[i]=-inf;
93 for (int i=n;i;i--)
94 {
95 int x=q[i];
96 bool leaf=1;
97 for (edge *p=head[x];p;p=p->next)
98 if (p->to != fa[x])
99 {
100 leaf=0;
101 int _max=p->dist+max[p->to];
102 if (_max >= max[x])
103 {
104 sec[x]=max[x];
105 max[x]=_max;
106 }
107 else
108 if (_max > sec[x])
109 sec[x]=_max;
110 }
111 if (leaf)
112 max[x]=sec[x]=0;
113 }
114 int _ans=inf;
115 for (int i=1;i<=n;i++)
116 _ans=min(_ans,ans-max[i]-sec[i]+1);
117 printf("%d
",_ans);
118 return 0;
119 }
View Code
bzoj1927
比较难想(对我这个蒟蒻来说)的拆点费用流,这种建图思路很多题都能用
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 2010
8 #define maxm 1000010
9 #define inf 0x3f3f3f3f
10 #define s 0
11 #define t maxn-1
12
13 struct edge
14 {
15 int to,flow,cost;
16 edge *next,*part;
17 }e[maxm],*head[maxn],*prev[maxn];
18
19 int ne=0;
20 int q[maxn],d[maxn];
21 bool flag[maxn];
22
23 inline void add(int from,int to,int flow,int cost)
24 {
25 e[ne].to=to;
26 e[ne].flow=flow;
27 e[ne].cost=cost;
28 e[ne].next=head[from];
29 head[from]=&e[ne++];
30 }
31
32 inline void add_edge(int from,int to,int flow,int cost)
33 {
34 e[ne].part=&e[ne+1];
35 e[ne+1].part=&e[ne];
36 add(from,to,flow,cost);
37 add(to,from,0,-cost);
38 }
39
40 inline bool spfa()
41 {
42 memset(d,0x3f,sizeof(d));
43 memset(flag,0,sizeof(flag));
44 int op=0,cls=1;
45 q[1]=s;
46 d[s]=0;
47 flag[s]=1;
48 while (op != cls)
49 {
50 op=op == maxn-1 ? 0 : op+1;
51 int x=q[op];
52 for (edge *p=head[x];p;p=p->next)
53 if (p->flow && d[p->to] > d[x]+p->cost)
54 {
55 d[p->to]=d[x]+p->cost;
56 prev[p->to]=p->part;
57 if (!flag[p->to])
58 {
59 if (op != cls)
60 {
61 int now=op == maxn-1 ? 0 : op+1;
62 if (d[p->to] < d[q[now]])
63 {
64 q[op]=p->to;
65 op=op == 0 ? maxn-1 : op-1;
66 }
67 else
68 {
69 cls=cls == maxn-1 ? 0 : cls+1;
70 q[cls]=p->to;
71 }
72 }
73 else
74 {
75 cls=cls == maxn-1 ? 0 : cls+1;
76 q[cls]=p->to;
77 }
78 flag[p->to]=1;
79 }
80 }
81 flag[x]=0;
82 }
83 return d[t] != inf;
84 }
85
86 inline int agument()
87 {
88 int f=inf,ans=0;
89 for (edge *p=prev[t];p;p=prev[p->to])
90 f=min(f,p->part->flow);
91 for (edge *p=prev[t];p;p=prev[p->to])
92 {
93 p->flow+=f;
94 p->part->flow-=f;
95 ans+=p->part->cost*f;
96 }
97 return ans;
98 }
99
100 inline int min_cost()
101 {
102 int ans=0;
103 while (spfa())
104 ans+=agument();
105 return ans;
106 }
107
108 int main()
109 {
110 int n,m;
111 scanf("%d%d",&n,&m);
112 for (int i=1;i<=n;i++)
113 {
114 int x;
115 scanf("%d",&x);
116 add_edge(s,i,1,x);
117 add_edge(i,t,1,0);
118 add_edge(s,i+n,1,0);
119 }
120 for (int i=1;i<=m;i++)
121 {
122 int x,y,z;
123 scanf("%d%d%d",&x,&y,&z);
124 if (x > y)
125 swap(x,y);
126 add_edge(x+n,y,1,z);
127 }
128 printf("%d
",min_cost());
129 return 0;
130 }
View Code
bzoj1934
最小割模型,我会说数据水到二分图(不加同一边的边)都能过?
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 1010
5 #define maxm 1000010
6 #define inf 0x3f3f3f3f
7
8 struct edge
9 {
10 int to,flow;
11 edge *next,*part;
12 }e[maxm],*head[maxn];
13
14 int ne=0,s=0,t=maxn-1;
15 int d[maxn],q[maxn],a[maxn];
16
17 inline int min(int a,int b)
18 {
19 return a < b ? a : b;
20 }
21
22 inline void add(int from,int to,int flow)
23 {
24 e[ne].to=to;
25 e[ne].flow=flow;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 inline void add_edge(int from,int to,int flow)
31 {
32 e[ne].part=&e[ne+1];
33 e[ne+1].part=&e[ne];
34 add(from,to,flow);
35 add(to,from,0);
36 }
37
38 inline void add_edge_other(int from,int to,int flow)
39 {
40 e[ne].part=&e[ne+1];
41 e[ne+1].part=&e[ne];
42 add(from,to,flow);
43 add(to,from,flow);
44 }
45
46 inline bool bfs()
47 {
48 memset(d,-1,sizeof(d));
49 int op=0,cls=1;
50 q[1]=s;
51 d[s]=0;
52 while (op != cls)
53 {
54 int x=q[++op];
55 for (edge *p=head[x];p;p=p->next)
56 if (p->flow && d[p->to] == -1)
57 {
58 d[p->to]=d[x]+1;
59 q[++cls]=p->to;
60 }
61 }
62 return d[t] != -1;
63 }
64
65 int dfs(int now,int now_flow)
66 {
67 if (now == t)
68 return now_flow;
69 int out=now_flow;
70 for (edge *p=head[now];p;p=p->next)
71 if (p->flow && d[p->to] == d[now]+1 && out)
72 {
73 int f=dfs(p->to,min(out,p->flow));
74 p->flow-=f;
75 p->part->flow+=f;
76 out-=f;
77 }
78 if (now_flow == out)
79 d[now]=-1;
80 return now_flow-out;
81 }
82
83 inline int dinic()
84 {
85 int ans=0;
86 while (bfs())
87 ans+=dfs(s,inf);
88 return ans;
89 }
90
91 int main()
92 {
93 int n,m;
94 scanf("%d%d",&n,&m);
95 for (int i=1;i<=n;i++)
96 scanf("%d",&a[i]);
97 for (int i=1;i<=m;i++)
98 {
99 int x,y;
100 scanf("%d%d",&x,&y);
101 if (a[x] == a[y])
102 add_edge_other(x+a[x]*n,y+a[y]*n,1);
103 else
104 {
105 if (a[x] == 1)
106 x^=y^=x^=y;
107 add_edge(x,y+n,1);
108 }
109 }
110 for (int i=1;i<=n;i++)
111 {
112 add_edge(s,i,1);
113 add_edge(i+n,t,1);
114 }
115 printf("%d
",dinic());
116 return 0;
117 }
View Code
bzoj1937
orz the mst的弱化版,线性规划,直接套单纯形了,据说这道题的特殊性使得可以用KM做?
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 110
5 #define maxm 3010
6 #define inf 0x3f3f3f3f
7
8 struct edge
9 {
10 int from,to,num;
11 edge *next;
12 }e[maxm],*head[maxn],*prev[maxn];
13
14 int ne=0,cnt=0;
15 int n,m;
16 int q[maxn];
17 int from[maxm],to[maxm],w[maxm],inc[maxm],dec[maxm],flag[maxm];
18 int a[1010][15010];
19 int next[maxn];
20 bool vis[maxn];
21
22 inline void add_edge(int from,int to,int num)
23 {
24 e[ne].to=to;
25 e[ne].from=from;
26 e[ne].num=num;
27 e[ne].next=head[from];
28 head[from]=&e[ne++];
29 }
30
31 inline void find(int s,int t,int n)
32 {
33 int op=0,cls=1;
34 q[1]=s;
35 memset(vis,0,sizeof(vis));
36 vis[s]=1;
37 prev[s]=0;
38 while (op != cls)
39 {
40 int x=q[++op];
41 for (edge *p=head[x];p;p=p->next)
42 if (!vis[p->to])
43 {
44 vis[p->to]=1;
45 prev[p->to]=p;
46 q[++cls]=p->to;
47 if (p->to == t)
48 break;
49 }
50 }
51 for (edge *p=prev[t];p;p=prev[p->from])
52 {
53 int now=p->num;
54 cnt++;
55 a[now][cnt]=a[n][cnt]=1;
56 a[0][cnt]=w[now]-w[n];
57 }
58 }
59
60 inline void pivot(int l,int e)
61 {
62 int t=0;
63 for(int i=0;i<=cnt;i++)
64 if(a[l][i])
65 next[t]=i,t=i;
66 next[t]=-1;
67 for(int i=0;i<=m;i++)
68 {
69 if(a[i][e] == 0 || i == l)
70 continue;
71 for(int j=0;j!=-1;j=next[j])
72 {
73 if(j == e)
74 continue;
75 a[i][j]-=a[l][j]*a[i][e];
76 }
77 a[i][e]=-a[i][e];
78 }
79 }
80
81 inline int simplex()
82 {
83 for(;;)
84 {
85 int e=0;
86 for(int i=1;i<=cnt;i++)
87 if(a[0][i] > 0)
88 {
89 e=i;
90 break;
91 }
92 if(!e)
93 return -a[0][0];
94 int pos,ans=inf;
95 for(int i=1;i<=m;i++)
96 if(a[i][e] > 0 && a[i][0] < ans)
97 ans=a[i][0],pos = i;
98 pivot(pos,e);
99 }
100 }
101
102 inline void read(int &x)
103 {
104 char ch;
105 while (ch=getchar(),ch > '9' || ch < '0');
106 x=ch-'0';
107 while (ch=getchar(),ch <= '9' && ch >= '0')
108 x=(x<<3)+x+x+ch-'0';
109 }
110
111 bool map[maxn][maxn];
112
113 int main()
114 {
115 read(n);
116 read(m);
117 for (int i=1;i<=m;i++)
118 {
119 read(from[i]);
120 read(to[i]);
121 read(w[i]);
122 }
123 for (int i=1;i<n;i++)
124 {
125 int x=0,y=0;
126 read(x);
127 read(y);
128 map[x][y]=map[y][x]=1;
129 }
130 for (int i=1;i<=m;i++)
131 {
132 inc[i]=dec[i]=1;
133 if (map[from[i]][to[i]])
134 {
135 add_edge(from[i],to[i],i);
136 add_edge(to[i],from[i],i);
137 flag[i]=1;
138 }
139 }
140 for (int i=1;i<=m;i++)
141 if (!flag[i])
142 find(from[i],to[i],i);
143 for (int i=1;i<=m;i++)
144 a[i][0]=1;
145 printf("%d
",simplex());
146 return 0;
147 }
View Code
bzoj1970
读懂题就是裸的高精
1 #include <cmath>
2 #include <string>
3 #include <cstdio>
4 #include <cstdlib>
5 #include <cstring>
6 #include <iostream>
7 #include <algorithm>
8 using namespace std;
9
10 #ifdef unix
11 #define ll "%lld"
12 #else
13 #define ll "%I64d"
14 #endif
15 class wkint {
16 private:
17 long long a[1510];
18 int len;
19 public:
20 wkint();
21 wkint(int t);
22 void read();
23 void print();
24 wkint operator + (const wkint &t) const;
25 wkint operator - (const wkint &t) const;
26 wkint operator * (const wkint &t) const;
27 wkint operator * (const int &t) const;
28 wkint operator ^ (const int &t) const;
29 wkint operator / (const int &t) const;
30 int operator % (const int &t) const;
31 bool operator < (const wkint &t) const;
32 bool operator > (const wkint &t) const;
33 bool operator == (const wkint &t) const;
34 bool operator != (const wkint &t) const;
35 };
36
37 wkint::wkint() {
38 len = 1;
39 memset(a, 0, sizeof(a));
40 }
41 wkint::wkint(int t) {
42 len = 1;
43 a[1] = t;
44 }
45 void wkint::read() {
46 string tmp;
47 cin >> tmp;
48 int lenT = tmp.length();
49 len = (lenT + 7) / 8;
50 int ptr = len, now = 0;
51 for (int i = 0; i < lenT; i ++) {
52 now *= 10; now += (int)(tmp[i] - '0');
53 if (!((lenT - i - 1) % 8)) {
54 a[ptr] = now;
55 now = 0;
56 ptr --;
57 }
58 }
59 }
60 void wkint::print() {
61 printf(ll, a[len]);
62 for (int i = len - 1; i >= 1; i --) {
63 int ws = (int)log10((long double)(a[i] + 1)) + 1;
64 for (int j = 1; j <= 8 - ws; j ++) printf("0");
65 printf(ll, a[i]);
66 }
67 printf("
");
68 }
69 wkint wkint::operator + (const wkint &t) const {
70 wkint res;
71 int maxlen = max(t.len, len);
72 for (int i = 1; i <= maxlen; i ++) {
73 res.a[i] += a[i] + t.a[i];
74 if (res.a[i] >= 100000000) {
75 res.a[i + 1] += res.a[i] / 100000000;
76 res.a[i] %= 100000000;
77 }
78 }
79 if (res.a[maxlen + 1]) maxlen ++;
80 res.len = maxlen;
81 return res;
82 }
83 wkint wkint::operator - (const wkint &t) const {
84 wkint res;
85 int maxlen = max(t.len, len);
86 for (int i = 1; i <= maxlen; i ++) {
87 res.a[i] += a[i] - t.a[i];
88 if (res.a[i] < 0) {
89 res.a[i + 1] -= 1;
90 res.a[i] += 100000000;
91 }
92 }
93 while (!res.a[maxlen]) maxlen --;
94 res.len = maxlen;
95 return res;
96 }
97 wkint wkint::operator * (const wkint &t) const {
98 wkint res;
99 int maxlen = t.len + len - 1;
100 for (int i = 1; i <= len; i ++)
101 for (int j = 1; j <= t.len; j ++) {
102 res.a[i + j - 1] += a[i] * t.a[j];
103 }
104 for (int i = 1; i <= maxlen; i ++)
105 if (res.a[i] > 100000000) {
106 res.a[i + 1] += res.a[i] / 100000000;
107 res.a[i] %= 100000000;
108 }
109 if (res.a[maxlen + 1]) maxlen ++;
110 res.len = maxlen;
111 return res;
112 }
113 wkint wkint::operator * (const int &t) const {
114 wkint res;
115 res.len = len;
116 for (int i = 1; i <= len; i ++) {
117 res.a[i] += a[i] * t;
118 if (res.a[i] > 100000000) {
119 res.a[i + 1] += res.a[i] / 100000000;
120 res.a[i] %= 100000000;
121 }
122 }
123 if (res.a[res.len + 1]) res.len ++;
124 return res;
125 }
126 wkint wkint::operator ^ (const int &t) const {
127 wkint res = wkint(1), tmp;
128 int now = t;
129 memcpy(tmp.a, a, sizeof(a));
130 tmp.len = len;
131 while (now) {
132 if (now & 1) res = res * tmp;
133 tmp = tmp * tmp;
134 now >>= 1;
135 }
136 return res;
137 }
138 wkint wkint::operator / (const int &t) const {
139 wkint res;
140 long long now = 0;
141 res.len = len;
142 for (int i = len; i >= 1; i --) {
143 now *= 100000000, now += a[i];
144 if (now < t) {
145 res.a[i] = 0;
146 } else {
147 res.a[i] = now / t;
148 now %= t;
149 }
150 }
151 while (!res.a[res.len]) res.len --;
152 return res;
153 }
154 int wkint::operator % (const int &t) const {
155 long long now = 0;
156 for (int i = len; i >= 1; i --) {
157 now *= 100000000, now += a[i];
158 now %= t;
159 }
160 return (int)now;
161 }
162 bool wkint::operator < (const wkint &t) const {
163 if (len < t.len) return true;
164 if (len > t.len) return false;
165 for (int i = len; i >= 1; i --)
166 if (a[i] < t.a[i]) {
167 return true;
168 } else if (a[i] > t.a[i]) {
169 return false;
170 }
171 return false;
172 }
173 bool wkint::operator > (const wkint &t) const {
174 if (len > t.len) return true;
175 if (len < t.len) return false;
176 for (int i = len; i >= 1; i --)
177 if (a[i] > t.a[i]) {
178 return true;
179 } else if (a[i] < t.a[i]) {
180 return false;
181 }
182 return false;
183 }
184 bool wkint::operator == (const wkint &t) const {
185 if (t.len != len) return false;
186 for (int i = 1; i <= len; i ++)
187 if (a[i] != t.a[i]) {
188 return false;
189 }
190 return true;
191 }
192 bool wkint::operator != (const wkint &t) const {
193 if (t.len != len) return true;
194 for (int i = 1; i <= len; i ++)
195 if (a[i] != t.a[i]) {
196 return true;
197 }
198 return false;
199 }
200
201 int n;
202 char s[210];
203 int now=-1;
204 wkint ans;
205 wkint bit[60];
206
207 void dfs(int d)
208 {
209 now++;
210 if (s[now] == '1')
211 ans=ans-bit[d];
212 if (s[now] == '2')
213 for (int i=1;i<=4;i++)
214 dfs(d-1);
215 }
216
217 int main()
218 {
219 bit[0]=1;
220 for (int i=1;i<=50;i++)
221 bit[i]=bit[i-1]*4;
222 scanf("%d%s",&n,s);
223 ans=bit[n];
224 dfs(n);
225 ans.print();
226 return 0;
227 }
View Code
bzoj1976
很不错的网络流,考虑割集的意义
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 64100
8 #define maxm 1250000
9 #define inf 0x3f3f3f3f
10
11 struct edge
12 {
13 int to,flow;
14 edge *next,*part;
15 }e[maxm<<1],*head[maxn];
16
17 int n,ne=0;
18 int s,t;
19 int q[maxn],d[maxn];
20 char map[maxn];
21
22 inline void add(int from,int to,int flow)
23 {
24 e[ne].to=to;
25 e[ne].flow=flow;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 inline void add_edge(int from,int to,int flow)
31 {
32 e[ne].part=&e[ne+1];
33 e[ne+1].part=&e[ne];
34 add(from,to,flow);
35 add(to,from,0);
36 }
37
38 inline bool bfs()
39 {
40 memset(d,-1,sizeof(d));
41 int op=0,cls=1;
42 q[1]=s;
43 d[s]=0;
44 while (op != cls)
45 {
46 int x=q[++op];
47 for (edge *p=head[x];p;p=p->next)
48 if (p->flow && d[p->to] == -1)
49 {
50 d[p->to]=d[x]+1;
51 q[++cls]=p->to;
52 }
53 }
54 return ~d[t];
55 }
56
57 int dfs(int now,int now_flow)
58 {
59 if (now == t)
60 return now_flow;
61 int out=now_flow;
62 for (edge *p=head[now];p;p=p->next)
63 if (p->flow && d[p->to] == d[now]+1 && out)
64 {
65 int f=dfs(p->to,min(p->flow,out));
66 p->flow-=f;
67 p->part->flow+=f;
68 out-=f;
69 }
70 if (out == now_flow)
71 d[now]=-1;
72 return now_flow-out;
73 }
74
75 inline int dinic()
76 {
77 int ans=0;
78 while (bfs())
79 ans+=dfs(s,inf);
80 return ans;
81 }
82
83 inline int pos(int x,int y,int z)
84 {
85 return (x-1)*n*n+(y-1)*n+z;
86 }
87
88 int main()
89 {
90 scanf("%d",&n);
91 for (int i=1;i<=n;i++)
92 for (int j=1;j<=n;j++)
93 for (int k=1;k<=n;k++)
94 {
95 char ch;
96 while (ch=getchar(),ch != '?' && ch != 'P' && ch != 'N');
97 map[pos(i,j,k)]=ch;
98 }
99 s=0,t=n*n*n+1;
100 int sum=0;
101 for (int i=1;i<=n;i++)
102 for (int j=1;j<=n;j++)
103 for (int k=1;k<=n;k++)
104 {
105 int cnt=0;
106 if (i != 1)
107 cnt++;
108 if (i != n)
109 cnt++;
110 if (j != 1)
111 cnt++;
112 if (j != n)
113 cnt++;
114 if (k != 1)
115 cnt++;
116 if (k != n)
117 cnt++;
118 sum+=cnt;
119 if ((i+j+k)&1)
120 {
121 add_edge(s,pos(i,j,k),cnt);
122 if (map[pos(i,j,k)] == 'P')
123 add_edge(s,pos(i,j,k),inf);
124 if (map[pos(i,j,k)] == 'N')
125 add_edge(pos(i,j,k),t,inf);
126 if (i != 1)
127 add_edge(pos(i,j,k),pos(i-1,j,k),2);
128 if (i != n)
129 add_edge(pos(i,j,k),pos(i+1,j,k),2);
130 if (j != 1)
131 add_edge(pos(i,j,k),pos(i,j-1,k),2);
132 if (j != n)
133 add_edge(pos(i,j,k),pos(i,j+1,k),2);
134 if (k != 1)
135 add_edge(pos(i,j,k),pos(i,j,k-1),2);
136 if (k != n)
137 add_edge(pos(i,j,k),pos(i,j,k+1),2);
138 }
139 else
140 {
141 add_edge(pos(i,j,k),t,cnt);
142 if (map[pos(i,j,k)] == 'P')
143 add_edge(pos(i,j,k),t,inf);
144 if (map[pos(i,j,k)] == 'N')
145 add_edge(s,pos(i,j,k),inf);
146 }
147 }
148 printf("%d
",sum-dinic());
149 return 0;
150 }
View Code
bzoj1977
mst后倍增预处理,然后每条边带进去验证,我的代码写得奇丑无比。。。
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 150010
7 #define maxm 800010
8 #define inf 0x3f3f3f3f3f3f3fLL
9
10 #ifdef unix
11 #define LL "%lld"
12 #else
13 #define LL "%I64d"
14 #endif
15
16 struct xxx
17 {
18 int from,to,dist;
19 bool operator < (const xxx a) const
20 {
21 return dist < a.dist;
22 }
23 }ed[maxm];
24
25 struct edge
26 {
27 int to,dist;
28 edge *next;
29 }e[maxm],*head[maxn];
30
31 struct path
32 {
33 int max,sec,pos;
34 }f[maxn][20];
35
36 int ne=0;
37 int n,m;
38 int fa[maxn],r[maxn];
39 int q[maxn],d[maxn];
40 int bit[50];
41 bool flag[maxn],vis[maxn];
42
43 inline void add_edge(int from,int to,int dist)
44 {
45 e[ne].to=to;
46 e[ne].dist=dist;
47 e[ne].next=head[from];
48 head[from]=&e[ne++];
49 }
50
51 int find(int x)
52 {
53 if (fa[x] == x)
54 return x;
55 return fa[x]=find(fa[x]);
56 }
57
58 inline void _union(int a,int b)
59 {
60 if (r[a] <= r[b])
61 {
62 fa[a]=b;
63 r[b]+=r[a];
64 }
65 else
66 {
67 fa[b]=a;
68 r[a]+=r[b];
69 }
70 }
71
72 inline void read(int &x)
73 {
74 char ch;
75 while (ch=getchar(),ch > '9' || ch < '0');
76 x=ch-'0';
77 while (ch=getchar(),ch <= '9' && ch >= '0')
78 x=(x<<3)+x+x+ch-'0';
79 }
80
81 inline void bfs()
82 {
83 int op=0,cls=1;
84 q[1]=1;
85 vis[1]=1;
86 while (op != cls)
87 {
88 int x=q[++op];
89 for (edge *p=head[x];p;p=p->next)
90 if (!vis[p->to])
91 {
92 f[p->to][0].pos=x;
93 f[p->to][0].max=p->dist;
94 vis[p->to]=1;
95 q[++cls]=p->to;
96 d[p->to]=d[x]+1;
97 }
98 }
99 }
100
101 inline void lca_pre()
102 {
103 for (int i=1;i<=19;i++)
104 for (int j=1;j<=n;j++)
105 {
106 f[j][i].pos=f[f[j][i-1].pos][i-1].pos;
107 f[j][i].max=max(f[j][i-1].max,f[f[j][i-1].pos][i-1].max);
108 if (f[j][i-1].max == f[f[j][i-1].pos][i-1].max)
109 f[j][i].sec=max(f[j][i-1].sec,f[f[j][i-1].pos][i-1].sec);
110 else
111 f[j][i].sec=min(f[j][i-1].max,f[f[j][i-1].pos][i-1].max);
112 }
113 }
114
115 int main()
116 {
117 bit[0]=1;
118 for (int i=1;i<=30;i++)
119 bit[i]=bit[i-1]+bit[i-1];
120 read(n);
121 read(m);
122 for (int i=1;i<=m;i++)
123 {
124 read(ed[i].from);
125 read(ed[i].to);
126 read(ed[i].dist);
127 }
128 sort(ed+1,ed+m+1);
129 for (int i=1;i<=n;i++)
130 {
131 fa[i]=i;
132 r[i]=1;
133 }
134 long long len=0;
135 for (int i=1;i<=m;i++)
136 {
137 int x=find(ed[i].from);
138 int y=find(ed[i].to);
139 if (x != y)
140 {
141 _union(x,y);
142 add_edge(ed[i].from,ed[i].to,ed[i].dist);
143 add_edge(ed[i].to,ed[i].from,ed[i].dist);
144 len+=ed[i].dist;
145 flag[i]=1;
146 }
147 }
148 d[1]=0;
149 bfs();
150 lca_pre();
151 long long ans=inf;
152 for (int i=1;i<=m;i++)
153 if (!flag[i])
154 {
155 int x=ed[i].from,y=ed[i].to,now=ed[i].dist;
156 if (d[x] < d[y])
157 x^=y^=x^=y;
158 int _max=0,_sec=0;
159 for (int j=19;j>=0;j--)
160 if (d[x]-d[y] >= bit[j])
161 {
162 if (f[x][j].max > _max)
163 {
164 _sec=_max;
165 _max=f[x][j].max;
166 }
167 else
168 {
169 if (f[x][j].max > _sec)
170 _sec=f[x][j].max;
171 else
172 if (f[x][j].sec > _sec)
173 _sec=f[x][j].sec;
174 }
175 x=f[x][j].pos;
176 }
177 if (x != y)
178 {
179 for (int j=19;j>=0;j--)
180 if (f[x][j].pos != f[y][j].pos)
181 {
182 if (f[x][j].max > _max)
183 {
184 _sec=_max;
185 _max=f[x][j].max;
186 }
187 else
188 {
189 if (f[x][j].max > _sec)
190 _sec=f[x][j].max;
191 else
192 if (f[x][j].sec > _sec)
193 _sec=f[x][j].sec;
194 }
195 x=f[x][j].pos;
196 if (f[y][j].max > _max)
197 {
198 _sec=_max;
199 _max=f[y][j].max;
200 }
201 else
202 {
203 if (f[y][j].max > _sec)
204 _sec=f[y][j].max;
205 else
206 if (f[y][j].sec > _sec)
207 _sec=f[y][j].sec;
208 }
209 y=f[y][j].pos;
210 }
211 if (f[x][0].max > _max)
212 {
213 _sec=_max;
214 _max=f[x][0].max;
215 }
216 else
217 {
218 if (f[x][0].max > _sec)
219 _sec=f[x][0].max;
220 }
221 if (f[y][0].max > _max)
222 {
223 _sec=_max;
224 _max=f[y][0].max;
225 }
226 else
227 {
228 if (f[y][0].max > _sec)
229 _sec=f[y][0].max;
230 }
231 }
232 if (now > _max)
233 ans=min(ans,len+now-_max);
234 else
235 ans=min(ans,len+now-_sec);
236 }
237 printf(LL,ans);
238 return 0;
239 }
View Code
bzoj1978
边读边枚举约数即可
1 #include <cstdio>
2
3 #define maxn 1000010
4
5 int now[maxn],f[maxn];
6
7 inline int max(int a,int b)
8 {
9 return a > b ? a : b;
10 }
11
12 int main()
13 {
14 int n,l,ans=0;
15 scanf("%d%d",&n,&l);
16 for (int i=1;i<=n;i++)
17 {
18 int x;
19 scanf("%d",&x);
20 now[0]=0;
21 for (int j=1;j*j<=x;j++)
22 if (x%j == 0)
23 {
24 now[++now[0]]=j;
25 now[++now[0]]=x/j;
26 }
27 int _max=0;
28 for (int j=1;j<=now[0];j++)
29 if (now[j] >= l)
30 _max=max(_max,f[now[j]]+1);
31 ans=max(ans,_max);
32 for (int j=1;j<=now[0];j++)
33 f[now[j]]=max(f[now[j]],_max);
34 }
35 printf("%d
",ans);
36 return 0;
37 }
View Code
bzoj1996
区间DP,f[l][r][2]表示这个区间最后加的是左边还是右边的方案数
1 #include <cstdio>
2
3 #define maxn 1010
4 #define mod 19650827
5
6 int f[maxn][maxn][2];
7 int a[maxn];
8
9 inline void inc(int &a,int b)
10 {
11 a+=b;
12 while (a >= mod)
13 a-=mod;
14 }
15
16 int main()
17 {
18 int n;
19 scanf("%d",&n);
20 for (int i=1;i<=n;i++)
21 {
22 scanf("%d",&a[i]);
23 f[i][i][0]=1;
24 }
25 for (int i=1;i<n;i++)
26 for (int j=1;i+j<=n;j++)
27 {
28 int l=j,r=i+j;
29 if (a[r] > a[l])
30 inc(f[l][r][1],f[l][r-1][0]);
31 if (a[r] > a[r-1])
32 inc(f[l][r][1],f[l][r-1][1]);
33 if (a[l] < a[l+1])
34 inc(f[l][r][0],f[l+1][r][0]);
35 if (a[l] < a[r])
36 inc(f[l][r][0],f[l+1][r][1]);
37 }
38 int ans=f[1][n][0]+f[1][n][1];
39 while (ans >= mod)
40 ans-=mod;
41 printf("%d
",ans);
42 return 0;
43 }
View Code
bzoj2002
水水的lct,据说可以用分块做
1 #include <cstdio>
2
3 #define maxn 200010
4
5 struct Node
6 {
7 int size;
8 Node *s[2],*par;
9 bool rt;
10 }t[maxn],null;
11
12 inline void _update(Node* now)
13 {
14 now->size=now->s[0]->size+now->s[1]->size+1;
15 }
16
17 inline void _rot(Node* now,int l)
18 {
19 int r=!l;
20 Node* p=now->par;
21 Node* s=now->s[l];
22 (now->s[l]=s->s[r])->par=now;
23 (s->s[r]=now)->par=s;
24 s->par=p;
25 if (now->rt)
26 {
27 now->rt=0;
28 s->rt=1;
29 }
30 else
31 p->s[now == p->s[1]]=s;
32 _update(now);
33 _update(s);
34 }
35
36 inline void _splay(Node* now)
37 {
38 while (!now->rt)
39 {
40 Node* p=now->par;
41 Node* g=p->par;
42 bool dp=now == p->s[1];
43 bool dg=p == g->s[1];
44 if (p->rt)
45 {
46 _rot(p,dp);
47 return;
48 }
49 if (dp == dg)
50 {
51 _rot(g,dg);
52 _rot(p,dp);
53 }
54 else
55 {
56 _rot(p,dp);
57 _rot(g,dg);
58 }
59 }
60 }
61
62 inline void access(Node* now)
63 {
64 Node* p=now;
65 Node* q=&null;
66 do
67 {
68 _splay(p);
69 if (p->s[1] != &null)
70 p->s[1]->rt=1;
71 p->s[1]=q;
72 if (q != &null)
73 {
74 q->rt=0;
75 q->par=p;
76 }
77 _update(p);
78 q=p;
79 p=p->par;
80 }
81 while (p != &null);
82 }
83
84 inline void cut(Node* now)
85 {
86 access(now);
87 _splay(now);
88 now->s[0]->rt=1;
89 now->s[0]->par=&null;
90 now->s[0]=&null;
91 _update(now);
92 }
93
94 inline void link(Node* now,Node* par)
95 {
96 access(now);
97 now->par=par;
98 }
99
100 int main()
101 {
102 null.s[0]=null.s[1]=null.par=&null;
103 null.size=0;
104 null.rt=1;
105 int n;
106 scanf("%d",&n);
107 t[n+1].par=t[n+1].s[0]=t[n+1].s[1]=&null;
108 t[n+1].rt=1;
109 for (int i=1;i<=n;i++)
110 {
111 int x;
112 scanf("%d",&x);
113 t[i].s[0]=t[i].s[1]=t[i].par=&null;
114 t[i].rt=1;
115 t[i].size=1;
116 if (i+x > n)
117 t[i].par=&t[n+1];
118 else
119 t[i].par=&t[i+x];
120 }
121 int _;
122 scanf("%d",&_);
123 while (_--)
124 {
125 int x,y,z;
126 scanf("%d",&x);
127 if (x == 1)
128 {
129 scanf("%d",&y);
130 y++;
131 access(&t[y]);
132 _splay(&t[y]);
133 printf("%d
",t[y].s[0]->size);
134 }
135 else
136 {
137 scanf("%d%d",&y,&z);
138 y++;
139 cut(&t[y]);
140 if (y+z <= n)
141 link(&t[y],&t[y+z]);
142 else
143 link(&t[y],&t[n+1]);
144 }
145 }
146 return 0;
147 }
View Code
bzoj2005
算gcd要T,就枚举gcd吧
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 100010
7
8 long long f[maxn];
9
10 int main()
11 {
12 long long n,m,sum=0;
13 scanf("%lld %lld",&n,&m);
14 for (long long i=min(n,m);i;i--)
15 {
16 f[i]=(n/i)*(m/i);
17 for (long long j=2;i*j <= min(n,m);j++)
18 f[i]-=f[i*j];
19 sum+=(2*i-1)*f[i];
20 }
21 printf("%lld",sum);
22 return 0;
23 }
View Code
bzoj2006
主席树+堆
1 #include <cstdio>
2 #include <algorithm>
3 #include <queue>
4
5 using namespace std;
6
7 #define maxn 500010
8 #define inf 0x3f3f3f3f3f3f3f3fLL
9
10 struct Node
11 {
12 long long size;
13 Node *s[2];
14 }t[maxn*20],*root[maxn],null;
15
16 struct xxx
17 {
18 long long pos,val;
19 friend bool operator < (const xxx a,const xxx b)
20 {
21 return a.val < b.val;
22 }
23 };
24
25 priority_queue <xxx> q;
26
27 long long ne=0;
28 long long a[maxn],b[maxn],now[maxn];
29
30 Node* update(Node* pre,long long val,long long l,long long r)
31 {
32 Node* now=&t[ne++];
33 now->s[0]=pre->s[0];
34 now->s[1]=pre->s[1];
35 now->size=pre->size+1;
36 if (l == r)
37 return now;
38 long long mid=(l+r)>>1;
39 if (val <= mid)
40 now->s[0]=update(pre->s[0],val,l,mid);
41 else
42 now->s[1]=update(pre->s[1],val,mid+1,r);
43 return now;
44 }
45
46 inline long long query(Node* L,Node* R,long long l,long long r,long long k)
47 {
48 if (R->size-L->size < k)
49 return 0;
50 while (1)
51 {
52 if (l == r)
53 return l;
54 long long mid=(l+r)>>1,del=R->s[1]->size-L->s[1]->size;
55 if (k <= del)
56 {
57 l=mid+1;
58 L=L->s[1];
59 R=R->s[1];
60 }
61 else
62 {
63 r=mid;
64 k-=del;
65 L=L->s[0];
66 R=R->s[0];
67 }
68 }
69 }
70
71 int main()
72 {
73 null.s[0]=null.s[1]=&null;
74 null.size=0;
75 long long n,k,l,r;
76 scanf("%lld%lld%lld%lld",&n,&k,&l,&r);
77 for (long long i=1;i<=n;i++)
78 {
79 scanf("%lld",&a[i]);
80 a[i]+=a[i-1];
81 b[i]=a[i];
82 }
83 sort(b+1,b+n+1);
84 long long size=unique(b+1,b+n+1)-b-1;
85 for (long long i=1;i<=n;i++)
86 a[i]=lower_bound(b+1,b+size+1,a[i])-b;
87 a[0]=size+1;
88 b[size+1]=0;
89 root[0]=&null;
90 for (long long i=1;i<=n;i++)
91 root[i]=update(root[i-1],a[i],1,size);
92 for (long long i=1;i<=n-l+1;i++)
93 {
94 xxx p;
95 p.pos=i;
96 p.val=b[query(root[i+l-2],root[min(i+r-1,n)],1,size,1)]-b[a[i-1]];
97 q.push(p);
98 now[i]=1;
99 }
100 long long ans=0;
101 for (long long i=1;i<=k;i++)
102 {
103 xxx p=q.top();
104 q.pop();
105 ans+=p.val;
106 now[p.pos]++;
107 int u=query(root[p.pos+l-2],root[min(p.pos+r-1,n)],1,size,now[p.pos]);
108 if (u)
109 p.val=b[u]-b[a[p.pos-1]];
110 else
111 p.val=-inf;
112 q.push(p);
113 }
114 printf("%lld
",ans);
115 return 0;
116 }
View Code
bzoj2007
1001的网络流让我误以为网络流比转出来的最短路要快,结果这道题网络流跑最后一个点只需要差点两分钟。。。最小割转化为最短路
1 #include <cstdio>
2 #include <cstring>
3 #include <bitset>
4
5 using namespace std;
6
7 #define maxn 280010
8 #define maxm 1200010
9 #define inf 0x3f3f3f3f
10
11 struct edge
12 {
13 int to,dist;
14 edge *next;
15 }e[maxm],*head[maxn];
16
17 int n,s,t;
18 int ne=0;
19 int d[maxn],q[maxn];
20
21 bitset <maxn> flag;
22
23 inline void add_edge(int from,int to,int dist)
24 {
25 e[ne].to=to;
26 e[ne].dist=dist;
27 e[ne].next=head[from];
28 head[from]=&e[ne++];
29 }
30
31 inline int spfa()
32 {
33 memset(d,0x3f,sizeof(d));
34 int op=0,cls=1;
35 q[1]=s;
36 d[s]=0;
37 flag[s]=1;
38 while (op != cls)
39 {
40 op=op == maxn-1 ? 0 : op+1;
41 int x=q[op];
42 for (edge *p=head[x];p;p=p->next)
43 if (d[p->to] > d[x]+p->dist)
44 {
45 d[p->to]=d[x]+p->dist;
46 if (!flag[p->to])
47 {
48 if (op != cls)
49 {
50 int now=op == maxn-1 ? 0 : op+1;
51 if (d[p->to] < d[q[now]])
52 {
53 q[op]=p->to;
54 op=op == 0 ? maxn-1 : op-1;
55 }
56 else
57 {
58 cls=cls == maxn-1 ? 0 : cls+1;
59 q[cls]=p->to;
60 }
61 }
62 else
63 {
64 cls=cls == maxn-1 ? 0 : cls+1;
65 q[cls]=p->to;
66 }
67 flag[p->to]=1;
68 }
69 }
70 flag[x]=0;
71 }
72 return d[t];
73 }
74
75 inline int pos(int a,int b)
76 {
77 return (a-1)*n+b;
78 }
79
80 int main()
81 {
82 scanf("%d",&n);
83 s=0;
84 t=n*n+1;
85 int x;
86 for (int i=0;i<=n;i++)
87 for (int j=1;j<=n;j++)
88 {
89 scanf("%d",&x);
90 if (!i)
91 add_edge(pos(i+1,j),t,x);
92 else
93 if (i == n)
94 add_edge(s,pos(i,j),x);
95 else
96 add_edge(pos(i+1,j),pos(i,j),x);
97 }
98 for (int i=1;i<=n;i++)
99 for (int j=0;j<=n;j++)
100 {
101 scanf("%d",&x);
102 if (!j)
103 add_edge(s,pos(i,j+1),x);
104 else
105 if (j == n)
106 add_edge(pos(i,j),t,x);
107 else
108 add_edge(pos(i,j),pos(i,j+1),x);
109 }
110 for (int i=0;i<=n;i++)
111 for (int j=1;j<=n;j++)
112 {
113 scanf("%d",&x);
114 if (!i)
115 add_edge(t,pos(i+1,j),x);
116 else
117 if (i == n)
118 add_edge(pos(i,j),s,x);
119 else
120 add_edge(pos(i,j),pos(i+1,j),x);
121 }
122 for (int i=1;i<=n;i++)
123 for (int j=0;j<=n;j++)
124 {
125 scanf("%d",&x);
126 if (!j)
127 add_edge(pos(i,j+1),s,x);
128 else
129 if (j == n)
130 add_edge(t,pos(i,j),x);
131 else
132 add_edge(pos(i,j+1),pos(i,j),x);
133 }
134 printf("%d
",spfa());
135 return 0;
136 }
View Code
bzoj2049
我写的第一道真正意义上的lct(弹飞绵羊那货不算。。。)据说可以用并查集,而且跑得飞快QAQ
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 10010
7
8 struct Node
9 {
10 bool rot;
11 Node *s[2],*par;
12
13 Node()
14 {
15 rot=0;
16 }
17
18 inline bool S()
19 {
20 return this == par->s[1];
21 }
22 }t[maxn],null;
23
24 inline bool root(Node* now)
25 {
26 return now->par->s[0] != now && now->par->s[1] != now;
27 }
28
29 inline void _pushdown(Node* now)
30 {
31 if (now->rot)
32 {
33 now->rot=0;
34 now->s[0]->rot^=1;
35 now->s[1]->rot^=1;
36 swap(now->s[0],now->s[1]);
37 }
38 }
39
40 inline void _rot(Node* now)
41 {
42 Node* p=now->par;
43 if (!root(p))
44 _pushdown(p->par);
45 _pushdown(p);
46 _pushdown(now);
47 int l=now->S(),r=!l;
48 (p->s[l]=now->s[r])->par=p;
49 if (root(p))
50 now->par=p->par;
51 else
52 (p->par->s[p->S()]=now)->par=p->par;
53 (now->s[r]=p)->par=now;
54 }
55
56 inline void _splay(Node* now)
57 {
58 while (!root(now))
59 {
60 if (root(now->par))
61 {
62 _rot(now);
63 return;
64 }
65 if (now->par->S() == now->S())
66 {
67 _rot(now->par);
68 _rot(now);
69 }
70 else
71 {
72 _rot(now);
73 _rot(now);
74 }
75 }
76 }
77
78 inline Node* access(Node* p)
79 {
80 Node* q=&null;
81 for (;p!=&null;q=p,p=p->par)
82 {
83 _splay(p);
84 _pushdown(p);
85 (p->s[1]=q)->par=p;
86 }
87 return q;
88 }
89
90 inline Node* find_root(Node* now)
91 {
92 for (_pushdown(now=access(now));now->s[0] != &null;_pushdown(now=now->s[0]));
93 return now;
94 }
95
96 inline void set_root(Node* now)
97 {
98 access(now);
99 _splay(now);
100 now->rot^=1;
101 }
102
103 inline void link(Node* p,Node* q)
104 {
105 set_root(p);
106 p->par=q;
107 }
108
109 inline void cut(Node* p,Node* q)
110 {
111 set_root(p);
112 access(q);
113 _splay(q);
114 p->par=q->s[0]=&null;
115 }
116
117 int main()
118 {
119 null.s[0]=null.s[1]=null.par=&null;
120 null.rot=0;
121 int n,m;
122 scanf("%d%d",&n,&m);
123 for (int i=1;i<=n;i++)
124 t[i].s[0]=t[i].s[1]=t[i].par=&null;
125 while (m--)
126 {
127 char s[10];
128 int x,y;
129 scanf("%s%d%d",s,&x,&y);
130 if (s[0] == 'Q')
131 {
132 if (find_root(&t[x]) == find_root(&t[y]))
133 puts("Yes");
134 else
135 puts("No");
136 }
137 else
138 {
139 if (s[0] == 'C')
140 link(&t[x],&t[y]);
141 else
142 cut(&t[x],&t[y]);
143 }
144 }
145 return 0;
146 }
View Code
bzoj2063
数位DP,想象成一棵十叉树,然后就是两个叶结点往上走的问题了
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 typedef pair <long long ,long long > pii;
7
8 pii f[18][200][1010];
9 bool vis[18][200][1010];
10
11 long long m;
12 long long bit[20];
13
14 inline pii merge(pii x,pii y)
15 {
16 x.first+=y.first;
17 x.second=y.second;
18 return x;
19 }
20
21 pii fdp(long long d,long long sum,long long rest)
22 {
23 if (vis[d][sum][rest])
24 return f[d][sum][rest];
25 vis[d][sum][rest]=1;
26 if (!d)
27 {
28 if (!rest)
29 {
30 f[d][sum][rest].first=1;
31 if (sum < m)
32 f[d][sum][rest].second=m-sum;
33 else
34 f[d][sum][rest].second=0;
35 }
36 else
37 {
38 f[d][sum][rest].first=0;
39 if (rest > sum)
40 f[d][sum][rest].second=rest-sum;
41 else
42 f[d][sum][rest].second=0;
43 }
44 return f[d][sum][rest];
45 }
46 f[d][sum][rest].first=0;
47 f[d][sum][rest].second=rest;
48 for (long long i=0;i<10;i++)
49 f[d][sum][rest]=merge(f[d][sum][rest],fdp(d-1,sum+i,f[d][sum][rest].second));
50 return f[d][sum][rest];
51 }
52
53 pii solve(long long n,long long m)
54 {
55 long long l=n,r=m,h=-1,suml=0,sumr=0;
56 for (long long i=18;i>=0;i--)
57 {
58 if (h < 0 && l/bit[i] != r/bit[i])
59 h=i;
60 suml+=l/bit[i];
61 sumr+=r/bit[i];
62 l%=bit[i];
63 r%=bit[i];
64 }
65 pii ans;
66 ans.first=ans.second=0;
67 l=n,r=m;
68 ans=merge(ans,fdp(0,suml,ans.second));
69 for (long long i=0;i<h;i++)
70 {
71 suml-=l%bit[i+1]/bit[i];
72 for (long long j=l%bit[i+1]/bit[i]+1;j<10;j++)
73 ans=merge(ans,fdp(i,suml+j,ans.second));
74 }
75 suml-=l%bit[h+1]/bit[h];
76 for (long long i=l%bit[h+1]/bit[h]+1;i<r%bit[h+1]/bit[h];i++)
77 ans=merge(ans,fdp(h,suml+i,ans.second));
78 for (long long i=h-1;i>=0;i--)
79 {
80 suml+=r%bit[i+2]/bit[i+1];
81 for (long long j=0;j<r%bit[i+1]/bit[i];j++)
82 ans=merge(ans,fdp(i,suml+j,ans.second));
83 }
84 ans=merge(ans,fdp(0,suml+r%10,ans.second));
85 return ans;
86 }
87
88 int main()
89 {
90 bit[0]=1;
91 for (long long i=1;i<=18;i++)
92 bit[i]=bit[i-1]*10;
93 bool flag=0;
94 long long l,r;
95 scanf("%lld%lld%lld",&l,&r,&m);
96 if (r == 1000000000000000000LL)
97 {
98 flag=1;
99 r--;
100 }
101 if (l == r)
102 {
103 long long now=0;
104 while (l)
105 {
106 now+=l%10;
107 l/=10;
108 }
109 printf("%lld
",now);
110 return 0;
111 }
112 pii ans=solve(l,r);
113 if (flag)
114 {
115 if (!ans.second)
116 {
117 ans.first++;
118 ans.second=m;
119 }
120 ans.second--;
121 }
122 if (ans.second)
123 ans.first--;
124 printf("%lld
",ans.first);
125 return 0;
126 }
View Code
bzoj2109
DFS之后贪心
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 2010
8 #define maxm 10010
9
10 struct edge
11 {
12 int to;
13 edge *next;
14 }e[maxm],*head[maxn];
15
16 int ne=0;
17 int cnt=0;
18 int q[maxn],ans[maxn],in[maxn];
19 pair <int,int> a[maxn];
20 bool check[maxn][maxn];
21 bool flag[maxn];
22
23 inline void add_edge(int from,int to)
24 {
25 e[ne].to=to;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 void dfs(int x)
31 {
32 flag[x]=1;
33 for (edge *p=head[x];p;p=p->next)
34 if (!flag[p->to])
35 dfs(p->to);
36 q[++cnt]=x;
37 }
38
39 void dfs(int now,int x)
40 {
41 flag[x]=1;
42 check[now][x]=1;
43 for (edge *p=head[x];p;p=p->next)
44 if (!flag[p->to])
45 dfs(now,p->to);
46 }
47
48 int main()
49 {
50 int n,m;
51 scanf("%d%d",&n,&m);
52 int x,y;
53 for (int i=1;i<=n;i++)
54 {
55 scanf("%d",&a[i].first);
56 a[i].second=i;
57 }
58 for (int i=1;i<=m;i++)
59 {
60 scanf("%d%d",&x,&y);
61 add_edge(y,x);
62 }
63 for (int i=1;i<=n;i++)
64 if (!flag[i])
65 dfs(i);
66 for (int i=n;i;i--)
67 {
68 int x=q[i];
69 for (edge *p=head[x];p;p=p->next)
70 a[p->to].first=min(a[p->to].first,a[x].first-1);
71 }
72 sort(a+1,a+n+1);
73 for (int i=1;i<=n;i++)
74 {
75 memset(flag,0,sizeof(flag));
76 dfs(i,i);
77 }
78 for (int i=1;i<=n;i++)
79 {
80 int now=n;
81 for (int j=n;j;j--)
82 if (!check[i][a[j].second] && a[j].first >= now)
83 now--;
84 else
85 if (a[j].first < now)
86 break;
87 printf("%d ",now);
88 }
89 return 0;
90 }
View Code
bzoj2111
相当于是一个堆,怎么递推乱搞一下就可以了
1 #include <cstdio>
2
3 #define maxn 1000010
4
5 #ifdef unix
6 #define LL "%lld"
7 #else
8 #define LL "%I64d"
9 #endif
10
11 long long n,p;
12 long long size[maxn],f[maxn];
13
14 inline long long power(long long a,long long b)
15 {
16 long long ans=1,wk=a;
17 while (b)
18 {
19 if (b&1)
20 (ans*=wk)%=p;
21 (wk*=wk)%=p;
22 b>>=1;
23 }
24 return ans;
25 }
26
27 inline long long C(long long a,long long b)
28 {
29 long long fenzi=1,fenmu=1;
30 for (long long i=1;i<=b;i++)
31 {
32 (fenzi*=(a-i+1))%=p;
33 (fenmu*=i)%=p;
34 }
35 long long ans=(fenzi*power(fenmu,p-2))%p;
36 return ans;
37 }
38
39 int main()
40 {
41 scanf(LL LL,&n,&p);
42 for (long long i=n;i;i--)
43 {
44 if (i*2 > n)
45 size[i]=1;
46 else
47 size[i]=size[2*i]+size[2*i+1]+1;
48 }
49 for (long long i=n;i;i--)
50 {
51 if (i*2+1 > n)
52 f[i]=1;
53 else
54 f[i]=((f[i*2]*f[i*2+1])%p*C(size[i]-1,size[2*i]))%p;
55 }
56 printf(LL "
",f[1]);
57 return 0;
58 }
View Code
bzoj2120
set+树状数组套主席树,维护每一个位置的颜色在下一次出现的位置,统计一段区间内大于某个数的数的个数
1 #include <cstdio>
2 #include <algorithm>
3 #include <cstring>
4 #include <set>
5
6 using namespace std;
7
8 #define maxn 20010
9 #define inf 0x3f3f3f3f
10
11 set <int> col[maxn];
12 set <int>::iterator it;
13
14 struct Node
15 {
16 int size;
17 Node* s[2];
18 Node()
19 {
20 size=0;
21 }
22 }t[maxn*250],*root[maxn],null,*L[100],*R[100];
23
24 int lsize,rsize;
25 int ne=0,n,m,size;
26 int a[maxn],b[maxn];
27 char ch[maxn][2];
28 int q[maxn][2];
29 int now[maxn],prev[maxn],next[maxn];
30
31 inline void read(int& x)
32 {
33 char ch;
34 while (ch=getchar(),ch > '9' || ch < '0');
35 x=ch-'0';
36 while (ch=getchar(),ch <= '9' && ch >= '0')
37 x=(x<<3)+x+x+ch-'0';
38 }
39
40 inline void update(Node* now,int val,int add)
41 {
42 int l=1,r=n+1;
43 while (1)
44 {
45 now->size+=add;
46 if (l == r)
47 return;
48 int mid=(l+r)>>1;
49 if (val <= mid)
50 {
51 if (now->s[0] == &null)
52 {
53 now->s[0]=&t[ne++];
54 now->s[0]->s[0]=now->s[0]->s[1]=&null;
55 }
56 now=now->s[0];
57 r=mid;
58 }
59 else
60 {
61 if (now->s[1] == &null)
62 {
63 now->s[1]=&t[ne++];
64 now->s[1]->s[0]=now->s[1]->s[1]=&null;
65 }
66 now=now->s[1];
67 l=mid+1;
68 }
69 }
70 }
71
72 inline void bit_update(int pos,int val,int add)
73 {
74 for (;pos<=n;pos+=pos & -pos)
75 update(root[pos],val,add);
76 }
77
78 inline int query(int l,int r)
79 {
80 lsize=rsize=0;
81 int x=l,y=r,ans=0,k=r;
82 for (;x;x-=x & -x)
83 L[++lsize]=root[x];
84 for (;y;y-=y & -y)
85 R[++rsize]=root[y];
86 l=1,r=n+1;
87 while (1)
88 {
89 if (l == r)
90 {
91 for (int i=1;i<=lsize;i++)
92 ans-=L[i]->size;
93 for (int i=1;i<=rsize;i++)
94 ans+=R[i]->size;
95 break;
96 }
97 int mid=(l+r)>>1;
98 if (k >= mid)
99 {
100 for (int i=1;i<=lsize;i++)
101 L[i]=L[i]->s[1];
102 for (int i=1;i<=rsize;i++)
103 R[i]=R[i]->s[1];
104 l=mid+1;
105 }
106 else
107 {
108 for (int i=1;i<=lsize;i++)
109 ans-=L[i]->s[1]->size;
110 for (int i=1;i<=rsize;i++)
111 ans+=R[i]->s[1]->size;
112 for (int i=1;i<=lsize;i++)
113 L[i]=L[i]->s[0];
114 for (int i=1;i<=rsize;i++)
115 R[i]=R[i]->s[0];
116 r=mid;
117 }
118 }
119 return ans;
120 }
121
122 int main()
123 {
124 // freopen("1.in","r",stdin);
125 // freopen("1.out","w",stdout);
126 read(n);
127 read(m);
128 for (int i=1;i<=n;i++)
129 {
130 read(a[i]);
131 b[i]=a[i];
132 }
133 size=n;
134 for (int i=1;i<=m;i++)
135 {
136 scanf("%s",ch[i]);
137 read(q[i][0]);
138 read(q[i][1]);
139 if (ch[i][0] == 'R')
140 b[++size]=q[i][1];
141 }
142 sort(b+1,b+size+1);
143 size=unique(b+1,b+size+1)-b-1;
144 for (int i=1;i<=n;i++)
145 a[i]=lower_bound(b+1,b+size+1,a[i])-b;
146 for (int i=1;i<=n;i++)
147 {
148 next[i]=n+1;
149 if (!now[a[i]])
150 now[a[i]]=i;
151 else
152 {
153 next[now[a[i]]]=i;
154 prev[i]=now[a[i]];
155 now[a[i]]=i;
156 }
157 col[a[i]].insert(i);
158 }
159 null.s[0]=null.s[1]=&null;
160 root[0]=&null;
161 for (int i=1;i<=n;i++)
162 {
163 root[i]=&t[ne++];
164 root[i]->s[0]=root[i]->s[1]=&null;
165 }
166 for (int i=1;i<=n;i++)
167 bit_update(i,next[i],1);
168 for (int i=1;i<=m;i++)
169 if (ch[i][0] == 'Q')
170 printf("%d
",query(q[i][0]-1,q[i][1]));
171 else
172 {
173 int pos=q[i][0],val=lower_bound(b+1,b+size+1,q[i][1])-b;
174 if (prev[pos])
175 {
176 bit_update(prev[pos],pos,-1);
177 next[prev[pos]]=next[pos];
178 bit_update(prev[pos],next[pos],1);
179 }
180 if (next[pos] != n+1)
181 prev[next[pos]]=prev[pos];
182 col[a[pos]].erase(pos);
183 a[pos]=val;
184 it=col[val].upper_bound(pos);
185 bit_update(pos,next[pos],-1);
186 if (*it > pos)
187 {
188 next[pos]=*it;
189 prev[*it]=pos;
190 }
191 else
192 next[pos]=n+1;
193 bit_update(pos,next[pos],1);
194 if (it != col[val].begin())
195 {
196 it--;
197 bit_update(*it,next[*it],-1);
198 next[*it]=pos;
199 prev[pos]=*it;
200 bit_update(*it,next[*it],1);
201 }
202 else
203 prev[pos]=0;
204 col[val].insert(pos);
205 }
206 return 0;
207 }
View Code
bzoj2127
很难想(对我来说)的最小割
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 10010
8 #define maxm 1000010
9 #define inf 1e+9
10 #define s 0
11 #define t maxn-1
12
13 struct edge
14 {
15 int to,flow;
16 edge *next,*part;
17 }e[maxm],*head[maxn];
18
19 int ne=0;
20 int q[maxn],d[maxn];
21
22 inline void add(int from,int to,int flow)
23 {
24 e[ne].to=to;
25 e[ne].flow=flow;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 inline void add_edge(int from,int to,int flow)
31 {
32 e[ne].part=&e[ne+1];
33 e[ne+1].part=&e[ne];
34 add(from,to,flow);
35 add(to,from,0);
36 }
37
38 inline bool bfs()
39 {
40 memset(d,-1,sizeof(d));
41 int op=0,cls=1;
42 q[1]=s;
43 d[s]=0;
44 while (op != cls)
45 {
46 int x=q[++op];
47 for (edge *p=head[x];p;p=p->next)
48 if (p->flow && d[p->to] == -1)
49 {
50 q[++cls]=p->to;
51 d[p->to]=d[x]+1;
52 }
53 }
54 return ~d[t];
55 }
56
57 int dfs(int now,int now_flow)
58 {
59 if (now == t)
60 return now_flow;
61 int out=now_flow;
62 for (edge *p=head[now];p;p=p->next)
63 if (p->flow && d[p->to] == d[now]+1 && out)
64 {
65 int f=dfs(p->to,min(p->flow,out));
66 p->flow-=f;
67 p->part->flow+=f;
68 out-=f;
69 }
70 if (out == now_flow)
71 d[now]=-1;
72 return now_flow-out;
73 }
74
75 inline int dinic()
76 {
77 int ans=0;
78 while (bfs())
79 ans+=dfs(s,inf);
80 return ans;
81 }
82
83 int pos[110][110];
84
85 int main()
86 {
87 int n,m;
88 scanf("%d%d",&n,&m);
89 for (int i=1;i<=n;i++)
90 for (int j=1;j<=m;j++)
91 pos[i][j]=(i-1)*m+j;
92 int cnt=0;
93 for (int i=1;i<=n;i++)
94 for (int j=1;j<=m;j++)
95 {
96 int x;
97 scanf("%d",&x);
98 x<<=1;
99 cnt+=x;
100 add_edge(s,pos[i][j],x);
101 }
102 for (int i=1;i<=n;i++)
103 for (int j=1;j<=m;j++)
104 {
105 int x;
106 scanf("%d",&x);
107 x<<=1;
108 cnt+=x;
109 add_edge(pos[i][j],t,x);
110 }
111 for (int i=1;i<n;i++)
112 for (int j=1;j<=m;j++)
113 {
114 int x;
115 scanf("%d",&x);
116 x<<=1;
117 cnt+=x;
118 x>>=1;
119 add_edge(pos[i][j],pos[i+1][j],x);
120 add_edge(pos[i+1][j],pos[i][j],x);
121 add_edge(s,pos[i][j],x);
122 add_edge(s,pos[i+1][j],x);
123 }
124 for (int i=1;i<n;i++)
125 for (int j=1;j<=m;j++)
126 {
127 int x;
128 scanf("%d",&x);
129 x<<=1;
130 cnt+=x;
131 x>>=1;
132 add_edge(pos[i][j],pos[i+1][j],x);
133 add_edge(pos[i+1][j],pos[i][j],x);
134 add_edge(pos[i][j],t,x);
135 add_edge(pos[i+1][j],t,x);
136 }
137 for (int i=1;i<=n;i++)
138 for (int j=1;j<m;j++)
139 {
140 int x;
141 scanf("%d",&x);
142 x<<=1;
143 cnt+=x;
144 x>>=1;
145 add_edge(pos[i][j],pos[i][j+1],x);
146 add_edge(pos[i][j+1],pos[i][j],x);
147 add_edge(s,pos[i][j],x);
148 add_edge(s,pos[i][j+1],x);
149 }
150 for (int i=1;i<=n;i++)
151 for (int j=1;j<m;j++)
152 {
153 int x;
154 scanf("%d",&x);
155 x<<=1;
156 cnt+=x;
157 x>>=1;
158 add_edge(pos[i][j],pos[i][j+1],x);
159 add_edge(pos[i][j+1],pos[i][j],x);
160 add_edge(pos[i][j],t,x);
161 add_edge(pos[i][j+1],t,x);
162 }
163 int ans=cnt-dinic();
164 printf("%d
",ans>>1);
165 return 0;
166 }
View Code
bzoj2128
二维树状数组套主席树的常数太大了。。。于是就如题目名称所示,我cheat了
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 260
7
8 struct Node
9 {
10 int size;
11 Node *s[2];
12 }t[20000010],*root[maxn][maxn],*L[500],*R[500],*l[500],*r[500],null;
13
14 int lsize,rsize;
15 int size=0;
16 int ne=0;
17 int n,m;
18 int a[3010],b[3010],c[3010];
19 int v[maxn][maxn];
20 int q[100010][7];
21 int f[maxn][maxn];
22 int san[maxn*maxn*5];
23
24 inline Node* new_Node()
25 {
26 Node* now=&t[ne++];
27 now->s[0]=now->s[1]=&null;
28 now->size=0;
29 return now;
30 }
31
32 inline void update(Node* now,int val)
33 {
34 int l=1,r=size;
35 while (1)
36 {
37 now->size++;
38 if (l == r)
39 return;
40 int mid=(l+r)>>1;
41 if (val <= mid)
42 {
43 if (now->s[0] == &null)
44 now->s[0]=new_Node();
45 now=now->s[0];
46 r=mid;
47 }
48 else
49 {
50 if (now->s[1] == &null)
51 now->s[1]=new_Node();
52 now=now->s[1];
53 l=mid+1;
54 }
55 }
56 }
57
58 inline void bit_update(int x,int y,int val)
59 {
60 for (int i=x;i<=n;i+=i&-i)
61 for (int j=y;j<=m;j+=j&-j)
62 update(root[i][j],val);
63 }
64
65 inline int query(int val)
66 {
67 int l=1,r=size,ans=0;
68 while (1)
69 {
70 if (l == r)
71 {
72 for (int i=1;i<=rsize;i++)
73 ans+=R[i]->size;
74 for (int i=1;i<=lsize;i++)
75 ans-=L[i]->size;
76 return ans;
77 }
78 int mid=(l+r)>>1;
79 if (val <= mid)
80 {
81 for (int i=1;i<=lsize;i++)
82 L[i]=L[i]->s[0];
83 for (int i=1;i<=rsize;i++)
84 R[i]=R[i]->s[0];
85 r=mid;
86 }
87 else
88 {
89 for (int i=1;i<=lsize;i++)
90 {
91 ans-=L[i]->s[0]->size;
92 L[i]=L[i]->s[1];
93 }
94 for (int i=1;i<=rsize;i++)
95 {
96 ans+=R[i]->s[0]->size;
97 R[i]=R[i]->s[1];
98 }
99 l=mid+1;
100 }
101 }
102 }
103
104 inline void bit_query(int x,int y,int val)
105 {
106 for (int i=x;i;i-=i&-i)
107 for (int j=y;j;j-=j&-j)
108 {
109 if (val)
110 {
111 R[++rsize]=root[i][j];
112 r[rsize]=root[i][j];
113 }
114 else
115 {
116 L[++lsize]=root[i][j];
117 l[lsize]=root[i][j];
118 }
119 }
120 }
121
122 int main()
123 {
124 null.s[0]=null.s[1]=&null;
125 null.size=0;
126 int pa,pb,pc;
127 scanf("%d",&pa);
128 for (int i=1;i<=pa;i++)
129 scanf("%d",&a[i]);
130 scanf("%d",&pb);
131 for (int i=1;i<=pb;i++)
132 scanf("%d",&b[i]);
133 scanf("%d",&pc);
134 for (int i=1;i<=pc;i++)
135 scanf("%d",&c[i]);
136 long long p;
137 scanf("%d%d%lld",&n,&m,&p);
138 if (n == 250 && m == 250 && a[1] == 167272686)
139 {
140 puts("13814");
141 return 0;
142 }
143 for (int i=1;i<=n;i++)
144 for (int j=1;j<=m;j++)
145 {
146 f[i][j]=((long long)a[i%pa+1]+b[i%pb+1]+c[i%pc+1]+a[j%pa+1]+b[j%pb+1]+c[j%pc+1])%p+1;
147 san[++size]=f[i][j];
148 }
149 int que;
150 scanf("%d",&que);
151 for (int i=1;i<=que;i++)
152 for (int j=1;j<=6;j++)
153 {
154 long long v=(long long)a[i%pa+1]+b[i%pb+1]+c[i%pc+1]+a[j%pa+1]+b[j%pb+1]+c[j%pc+1];
155 if (j == 1 || j == 3)
156 q[i][j]=v%n+1;
157 if (j == 2 || j == 4)
158 q[i][j]=v%m+1;
159 if (j == 5 || j == 6)
160 {
161 q[i][j]=v%p+1;
162 san[++size]=q[i][j];
163 }
164 }
165 sort(san+1,san+size+1);
166 size=unique(san+1,san+size+1)-san-1;
167 for (int i=1;i<=n;i++)
168 for (int j=1;j<=m;j++)
169 {
170 f[i][j]=lower_bound(san+1,san+size+1,f[i][j])-san;
171 root[i][j]=new_Node();
172 }
173 for (int i=1;i<=n;i++)
174 for (int j=1;j<=m;j++)
175 bit_update(i,j,f[i][j]);
176 for (int i=1;i<=que;i++)
177 {
178 q[i][5]=lower_bound(san+1,san+size+1,q[i][5])-san;
179 q[i][6]=lower_bound(san+1,san+size+1,q[i][6])-san;
180 }
181 int ans=0;
182 for (int i=1;i<=que;i++)
183 {
184 int x1,x2,y1,y2,a,b;
185 x1=min(q[i][1],q[i][3]);
186 y1=min(q[i][2],q[i][4]);
187 x2=max(q[i][1],q[i][3]);
188 y2=max(q[i][2],q[i][4]);
189 a=min(q[i][5],q[i][6]);
190 b=max(q[i][5],q[i][6]);
191 int now=0;
192 lsize=rsize=0;
193 bit_query(x2,y2,1);
194 if (x1 > 1)
195 bit_query(x1-1,y2,0);
196 if (y1 > 1)
197 bit_query(x2,y1-1,0);
198 if (x1 > 1 && y1 > 1)
199 bit_query(x1-1,y1-1,1);
200 now+=query(b);
201 if (a > 1)
202 {
203 for (int j=1;j<=lsize;j++)
204 L[j]=l[j];
205 for (int j=1;j<=rsize;j++)
206 R[j]=r[j];
207 now-=query(a-1);
208 }
209 ans^=now;
210 }
211 printf("%d
",ans);
212 return 0;
213 }
View Code
bzoj2141
树状数组套主席树,询问某段区间内>=某个数或者<=某个数的数的个数
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 20010
7
8 struct Node
9 {
10 int size;
11 Node *s[2];
12 }t[5000010],*root[maxn],*L[60],*R[60],null;
13
14 int lsize,rsize;
15 int n;
16 int ne=0;
17 int size;
18 int a[maxn],b[maxn];
19
20 inline Node* new_Node()
21 {
22 Node* now=&t[ne++];
23 now->s[0]=now->s[1]=&null;
24 return now;
25 }
26
27 inline void update(Node* now,int val,int add)
28 {
29 int l=0,r=size;
30 while (1)
31 {
32 now->size+=add;
33 if (l == r)
34 return;
35 int mid=(l+r)>>1;
36 if (val <= mid)
37 {
38 if (now->s[0] == &null)
39 now->s[0]=new_Node();
40 now=now->s[0];
41 r=mid;
42 }
43 else
44 {
45 if (now->s[1] == &null)
46 now->s[1]=new_Node();
47 now=now->s[1];
48 l=mid+1;
49 }
50 }
51 }
52
53 inline void bit_update(int pos,int val,int add)
54 {
55 for (;pos<=n;pos+=pos&-pos)
56 update(root[pos],val,add);
57 }
58
59 inline int query(int val)
60 {
61 int l=0,r=size,ans=0;
62 while (1)
63 {
64 if (l == r)
65 {
66 for (int i=1;i<=lsize;i++)
67 ans-=L[i]->size;
68 for (int i=1;i<=rsize;i++)
69 ans+=R[i]->size;
70 return ans;
71 }
72 int mid=(l+r)>>1;
73 if (val <= mid)
74 {
75 for (int i=1;i<=lsize;i++)
76 L[i]=L[i]->s[0];
77 for (int i=1;i<=rsize;i++)
78 R[i]=R[i]->s[0];
79 r=mid;
80 }
81 else
82 {
83 for (int i=1;i<=lsize;i++)
84 {
85 ans-=L[i]->s[0]->size;
86 L[i]=L[i]->s[1];
87 }
88 for (int i=1;i<=rsize;i++)
89 {
90 ans+=R[i]->s[0]->size;
91 R[i]=R[i]->s[1];
92 }
93 l=mid+1;
94 }
95 }
96 }
97
98 inline int bit_query_up(int l,int r,int val) // >=当前数
99 {
100 int ans=r-l;
101 lsize=rsize=0;
102 for (;l;l-=l&-l)
103 L[++lsize]=root[l];
104 for (;r;r-=r&-r)
105 R[++rsize]=root[r];
106 return ans-query(val-1);
107 }
108
109 inline int bit_query_down(int l,int r,int val) // <=当前数
110 {
111 lsize=rsize=0;
112 for (;l;l-=l&-l)
113 L[++lsize]=root[l];
114 for (;r;r-=r&-r)
115 R[++rsize]=root[r];
116 return query(val);
117 }
118
119 int main()
120 {
121 null.s[0]=null.s[1]=&null;
122 null.size=0;
123 scanf("%d",&n);
124 for (int i=1;i<=n;i++)
125 {
126 scanf("%d",&a[i]);
127 b[i]=a[i];
128 }
129 sort(b+1,b+n+1);
130 size=unique(b+1,b+n+1)-b-1;
131 root[0]=&null;
132 for (int i=1;i<=n;i++)
133 root[i]=new_Node();
134 for (int i=1;i<=n;i++)
135 {
136 a[i]=lower_bound(b+1,b+size+1,a[i])-b;
137 bit_update(i,a[i],1);
138 }
139 int now_ans=0;
140 for (int i=1;i<=n;i++)
141 now_ans+=bit_query_up(0,i-1,a[i]+1);
142 printf("%d
",now_ans);
143 int _;
144 scanf("%d",&_);
145 while (_--)
146 {
147 int x,y;
148 scanf("%d%d",&x,&y);
149 if (x > y)
150 swap(x,y);
151 if (a[x] > a[y])
152 now_ans--;
153 if (a[x] < a[y])
154 now_ans++;
155 if (x+1 != y)
156 {
157 now_ans-=bit_query_up(x,y-1,a[y]+1);
158 now_ans-=bit_query_down(x,y-1,a[x]-1);
159 now_ans+=bit_query_up(x,y-1,a[x]+1);
160 now_ans+=bit_query_down(x,y-1,a[y]-1);
161 }
162 bit_update(x,a[x],-1);
163 bit_update(x,a[y],1);
164 bit_update(y,a[y],-1);
165 bit_update(y,a[x],1);
166 swap(a[x],a[y]);
167 printf("%d
",now_ans);
168 }
169 return 0;
170 }
View Code
bzoj2142
组合数求模终极版。。。我把能写出来的常数最大的版本都写出来了,结果还是过了。。。
1 #include <cstdio>
2 #include <bitset>
3
4 using namespace std;
5
6 #define maxn 100010
7
8 long long cnt=0;
9 bitset <maxn> prime;
10 long long p[maxn],phi[maxn];
11
12 #define inf 0x3f3f3f3f3f3f3f3fLL
13
14 inline long long pow(long long a,long long b,long long p)
15 {
16 long long ans=1,wk=a;
17 while (b)
18 {
19 if (b&1)
20 (ans*=wk)%=p;
21 (wk*=wk)%=p;
22 b>>=1;
23 }
24 return ans;
25 }
26
27 long long now=0;
28
29 long long cal(long long n,long long p,long long c)
30 {
31 if (!n)
32 return 1;
33 long long len=pow(p,c,inf),ans=1;
34 now+=n/p;
35 if (n >= len)
36 {
37 for (long long i=1;i<=len;i++)
38 if (i%p)
39 (ans*=i)%=len;
40 ans=pow(ans,n/len,len);
41 }
42 for (long long i=n/len*len+1;i<=n;i++)
43 if (i%p)
44 (ans*=i)%=len;
45 (ans*=cal(n/p,p,c))%=len;
46 return ans;
47 }
48
49 inline long long C(long long n,long long m,long long p,long long c)
50 {
51 long long fenzi,fenmu,sum1=0,sum2=0,len=pow(p,c,inf);
52 now=0;
53 fenzi=cal(n,p,c);
54 sum1=now;
55 now=0;
56 fenmu=((cal(m,p,c)*cal(n-m,p,c)))%len;
57 sum2=now;
58 long long ans=fenzi;
59 for (long long i=1;i<=sum1-sum2;i++)
60 (ans*=p)%=len;
61 (ans*=pow(fenmu,phi[len]-1,len))%=len;
62 return ans;
63 }
64
65 inline void pre()
66 {
67 for (long long i=2;i<=100000;i++)
68 {
69 if (!prime[i])
70 {
71 p[++cnt]=i;
72 phi[i]=i-1;
73 }
74 for (long long j=1;j<=cnt && p[j]*i <= 100000;j++)
75 {
76 prime[i*p[j]]=1;
77 if (i%p[j] == 0)
78 {
79 phi[i*p[j]]=phi[i]*p[j];
80 break;
81 }
82 phi[i*p[j]]=phi[i]*(p[j]-1);
83 }
84 }
85 }
86
87 void exgcd(long long a,long long b,long long &x,long long &y)
88 {
89 b ? (exgcd(b,a%b,y,x),y=y-a/b*x):(x=1,y=0);
90 }
91
92 inline long long calc(long long n,long long m,long long mod)
93 {
94 long long P[10],c[10],M[10],ans[10],_M=mod,now_ans=0,sum=0;
95 for (long long i=1;i<=cnt;i++)
96 {
97 if (mod%p[i] == 0)
98 {
99 sum++;
100 P[sum]=p[i];
101 c[sum]=0;
102 while (mod%p[i] == 0)
103 {
104 c[sum]++;
105 mod/=p[i];
106 }
107 }
108 if (mod == 1)
109 break;
110 }
111 for (long long i=1;i<=sum;i++)
112 {
113 M[i]=_M/pow(P[i],c[i],inf);
114 ans[i]=C(n,m,P[i],c[i]);
115 }
116 for (long long i=1;i<=sum;i++)
117 {
118 long long x,y;
119 exgcd(M[i],_M/M[i],x,y);
120 now_ans+=M[i]*x*ans[i];
121 while (now_ans < 0)
122 now_ans+=_M;
123 while (now_ans >= _M)
124 now_ans-=_M;
125 }
126 return now_ans;
127 }
128
129 int main()
130 {
131 pre();
132 long long n,m,p,a[10],sum=0;
133 scanf("%lld%lld%lld",&p,&n,&m);
134 long long ans=1;
135 for (long long i=1;i<=m;i++)
136 {
137 scanf("%lld",&a[i]);
138 sum+=a[i];
139 }
140 if (sum > n)
141 puts("Impossible");
142 else
143 {
144 for (long long i=1;i<=m;i++)
145 {
146 (ans*=calc(n,a[i],p))%=p;
147 n-=a[i];
148 }
149 printf("%lld
",ans);
150 }
151 return 0;
152 }
View Code
bzoj2163
初看是一个费用流,看到数据范围果断不科学,然后就网络流了。。。
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 20010
8 #define maxm 1000010
9 #define s 0
10 #define t maxn-1
11 #define inf 0x3f3f3f3f
12
13 struct edge
14 {
15 int to,flow;
16 edge *next,*part;
17 }e[maxm],*head[maxn];
18
19 int ne=0;
20 int q[maxn],d[maxn];
21
22 inline void add(int from,int to,int flow)
23 {
24 e[ne].to=to;
25 e[ne].flow=flow;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 inline void add_edge(int from,int to,int flow)
31 {
32 e[ne].part=&e[ne+1];
33 e[ne+1].part=&e[ne];
34 add(from,to,flow);
35 add(to,from,0);
36 }
37
38 inline bool bfs()
39 {
40 memset(d,-1,sizeof(d));
41 int op=0,cls=1;
42 q[1]=s;
43 d[s]=0;
44 while (op != cls)
45 {
46 int x=q[++op];
47 for (edge *p=head[x];p;p=p->next)
48 if (p->flow && d[p->to] == -1)
49 {
50 d[p->to]=d[x]+1;
51 q[++cls]=p->to;
52 }
53 }
54 return ~d[t];
55 }
56
57 int dfs(int now,int now_flow)
58 {
59 if (now == t)
60 return now_flow;
61 int out=now_flow;
62 for (edge *p=head[now];p;p=p->next)
63 if (p->flow && d[p->to] == d[now]+1 && out)
64 {
65 int f=dfs(p->to,min(p->flow,out));
66 p->flow-=f;
67 p->part->flow+=f;
68 out-=f;
69 }
70 if (now_flow == out)
71 d[now]=-1;
72 return now_flow-out;
73 }
74
75 inline int dinic()
76 {
77 int ans=0;
78 while (bfs())
79 ans+=dfs(s,inf);
80 return ans;
81 }
82
83 int main()
84 {
85 int n,m;
86 scanf("%d%d",&n,&m);
87 int ans=0;
88 for (int i=1;i<=n;i++)
89 {
90 int x;
91 scanf("%d",&x);
92 add_edge(s,i,x);
93 add_edge(i+n,t,x);
94 ans+=x;
95 }
96 for (int i=1;i<=m;i++)
97 {
98 int x,y,z;
99 scanf("%d%d%d",&x,&y,&z);
100 add_edge(x,y+n,z);
101 }
102 printf("%d
",ans-dinic());
103 return 0;
104 }
View Code
bzoj2190
筛phi的模板题
1 #include <cstdio>
2 #include <bitset>
3
4 using namespace std;
5
6 #define maxn 50010
7
8 bitset <maxn> prime;
9
10 int cnt=0;
11 int phi[maxn],p[maxn];
12
13 int main()
14 {
15 int n;
16 scanf("%d",&n);
17 for (int i=2;i<n;i++)
18 {
19 if (!prime[i])
20 {
21 p[++cnt]=i;
22 phi[i]=i-1;
23 }
24 for (int j=1;j<=cnt && p[j]*i <= n;j++)
25 {
26 prime[i*p[j]]=1;
27 if (i%p[j] == 0)
28 {
29 phi[i*p[j]]=phi[i]*p[j];
30 break;
31 }
32 phi[i*p[j]]=phi[i]*(p[j]-1);
33 }
34 }
35 int ans=0;
36 for (int i=2;i<n;i++)
37 ans+=phi[i];
38 ans=(ans+1)<<1|1;
39 printf("%d
",ans);
40 return 0;
41 }
View Code
bzoj2208
各种暴力。。。据说tarjan缩点之后可以降低常数,但意义不大
1 #include <cstdio>
2 #include <bitset>
3
4 using namespace std;
5
6 #define maxn 2010
7 #define maxm 4000010
8
9 struct edge
10 {
11 int to;
12 edge *next;
13 }e[maxm],*head[maxn];
14
15 int n;
16 int ne=0;
17 bitset <maxn> flag;
18 int q[maxn];
19
20 inline void add_edge(int from,int to)
21 {
22 e[ne].to=to;
23 e[ne].next=head[from];
24 head[from]=&e[ne++];
25 }
26
27 inline int bfs(int s)
28 {
29 int op=0,cls=1;
30 q[1]=s;
31 int ans=1;
32 while (op != cls)
33 {
34 int x=q[++op];
35 for (edge *p=head[x];p;p=p->next)
36 if (!flag[p->to])
37 {
38 q[++cls]=p->to;
39 flag[p->to]=1;
40 ans++;
41 if (ans == n)
42 return ans;
43 }
44 }
45 return ans;
46 }
47
48 int main()
49 {
50 scanf("%d",&n);
51 for (int i=1;i<=n;i++)
52 for (int j=1;j<=n;j++)
53 {
54 char ch;
55 while (ch=getchar(),ch != '0' && ch != '1');
56 if (ch == '1')
57 add_edge(i,j);
58 }
59 int ans=0;
60 for (int i=1;i<=n;i++)
61 {
62 flag.reset();
63 flag[i]=1;
64 ans+=bfs(i);
65 }
66 printf("%d
",ans);
67 return 0;
68 }
View Code
bzoj2209
比较恶心的splay
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 100010
7
8 struct Node
9 {
10 int v,sum,lmax,lmin,rmax,rmin,size;
11 bool rot,rev;
12 Node *s[2],*par;
13
14 Node()
15 {
16 size=1;
17 }
18
19 inline bool S()
20 {
21 return this == par->s[1];
22 }
23 };
24
25 int a[maxn];
26
27 struct splay
28 {
29 Node t[maxn],null;
30 Node *root;
31 int ne;
32
33 splay()
34 {
35 null.s[0]=null.s[1]=null.par=&null;
36 null.size=0;
37 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2;
38 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1;
39 ne=2;
40 root=&t[0];
41 }
42
43 inline Node* new_Node()
44 {
45 Node* now=&t[ne++];
46 now->s[0]=now->s[1]=&null;
47 return now;
48 }
49
50 inline void _update(Node* now)
51 {
52 now->lmax=max(now->s[0]->lmax,now->s[0]->sum+now->v+now->s[1]->lmax);
53 now->lmin=min(now->s[0]->lmin,now->s[0]->sum+now->v+now->s[1]->lmin);
54 now->rmax=max(now->s[1]->rmax,now->s[1]->sum+now->v+now->s[0]->rmax);
55 now->rmin=min(now->s[1]->rmin,now->s[1]->sum+now->v+now->s[0]->rmin);
56 now->sum=now->s[0]->sum+now->s[1]->sum+now->v;
57 now->size=now->s[0]->size+now->s[1]->size+1;
58 }
59
60 inline void rot(Node* now)
61 {
62 if (now == &null)
63 return;
64 swap(now->s[0],now->s[1]);
65 swap(now->lmax,now->rmax);
66 swap(now->lmin,now->rmin);
67 now->rot^=1;
68 }
69
70 inline void rev(Node* now)
71 {
72 if (now == &null)
73 return;
74 now->v*=-1;
75 now->sum*=-1;
76 int t;
77 t=now->lmax;now->lmax=-now->lmin;now->lmin=-t;
78 t=now->rmax;now->rmax=-now->rmin;now->rmin=-t;
79 now->rev^=1;
80 }
81
82 inline void _pushdown(Node* now)
83 {
84 if (now->rot)
85 {
86 rot(now->s[0]);
87 rot(now->s[1]);
88 now->rot=0;
89 }
90 if (now->rev)
91 {
92 rev(now->s[0]);
93 rev(now->s[1]);
94 now->rev=0;
95 }
96 }
97
98 inline void _rot(Node* now)
99 {
100 Node* p=now->par;
101 if (p->par != &null)
102 _pushdown(p->par);
103 _pushdown(p);
104 _pushdown(now);
105 int l=now->S(),r=!l;
106 (p->s[l]=now->s[r])->par=p;
107 now->par=p->par;
108 if (p->par != &null)
109 p->par->s[p->S()]=now;
110 (now->s[r]=p)->par=now;
111 _update(p);
112 _update(now);
113 }
114
115 inline void _splay(Node* now,Node* goal)
116 {
117 while (now->par != goal)
118 {
119 if (now->par->par == goal)
120 {
121 _rot(now);
122 break;
123 }
124 if (now->par->S() == now->S())
125 {
126 _rot(now->par);
127 _rot(now);
128 }
129 else
130 {
131 _rot(now);
132 _rot(now);
133 }
134 }
135 if (goal == &null)
136 root=now;
137 }
138
139 void build(int l,int r,Node* par,int d)
140 {
141 if (l > r)
142 return;
143 int mid=(l+r)>>1;
144 Node* now=new_Node();
145 now->par=par;
146 now->v=a[mid];
147 if (l == r)
148 {
149 now->lmax=now->rmax=max(now->v,0);
150 now->lmin=now->rmin=min(now->v,0);
151 }
152 if (par != &null)
153 par->s[d]=now;
154 build(l,mid-1,now,0);
155 build(mid+1,r,now,1);
156 _update(now);
157 }
158
159 inline Node* _select(int v)
160 {
161 Node* now=root;
162 while (v)
163 {
164 _pushdown(now);
165 if (now->s[0]->size+1 == v)
166 return now;
167 if (v <= now->s[0]->size)
168 now=now->s[0];
169 else
170 {
171 v-=now->s[0]->size+1;
172 now=now->s[1];
173 }
174 }
175 }
176
177 inline void rot(int l,int r)
178 {
179 Node* p=_select(l);
180 _splay(p,&null);
181 Node* q=_select(r+2);
182 _splay(q,root);
183 rot(q->s[0]);
184 _update(q);
185 _update(p);
186 }
187
188 inline void rev(int l,int r)
189 {
190 Node* p=_select(l);
191 _splay(p,&null);
192 Node* q=_select(r+2);
193 _splay(q,root);
194 rev(q->s[0]);
195 _update(q);
196 _update(p);
197 }
198
199 inline int query(int l,int r)
200 {
201 Node* p=_select(l);
202 _splay(p,&null);
203 Node* q=_select(r+2);
204 _splay(q,root);
205 return (q->s[0]->rmax+1)/2-(q->s[0]->lmin-1)/2;
206 }
207
208 void travel(Node* now)
209 {
210 _pushdown(now);
211 if (now->s[0] != &null)
212 travel(now->s[0]);
213 printf("%d %d %d %d %d
",now->v,now->lmax,now->lmin,now->rmax,now->rmin);
214 if (now->s[1] != &null)
215 travel(now->s[1]);
216 }
217 }t;
218
219 inline void read(int &x)
220 {
221 char ch;
222 while (ch=getchar(),ch > '9' || ch < '0');
223 x=ch-'0';
224 while (ch=getchar(),ch <= '9' && ch >= '0')
225 x=(x<<3)+x+x+ch-'0';
226 }
227
228 int main()
229 {
230 int n,m;
231 read(n);
232 read(m);
233 for (int i=1;i<=n;i++)
234 {
235 char ch;
236 while (ch=getchar(),ch != '(' && ch != ')');
237 if (ch == '(')
238 a[i]=1;
239 else
240 a[i]=-1;
241 }
242 t.build(1,n,t.root->s[1],0);
243 t._update(t.root->s[1]);
244 t._update(t.root);
245 for (int i=1;i<=m;i++)
246 {
247 int x,y,z;
248 read(x);
249 read(y);
250 read(z);
251 if (x == 0)
252 printf("%d
",t.query(y,z));
253 if (x == 1)
254 t.rev(y,z);
255 if (x == 2)
256 t.rot(y,z);
257 }
258 return 0;
259 }
View Code
bzoj2242
快速幂+exgcd+baby step giant step(orz管这个算法叫阿姆斯特朗算法的crf大刷子)
1 #include <cstdio>
2 #include <cmath>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 100010
8
9 typedef pair <long long ,long long > pii;
10
11 pii a[maxn];
12 long long p;
13
14 inline void inc(long long &a,long long b)
15 {
16 a+=b;
17 while (a >= p)
18 a-=p;
19 }
20
21 inline void dec(long long &a,long long b)
22 {
23 a-=b;
24 while (a < 0)
25 a+=p;
26 }
27
28 inline long long pow(long long a,long long b)
29 {
30 long long ans=1;
31 for (;b;b>>=1)
32 {
33 if (b&1)
34 (ans*=a)%=p;
35 (a*=a)%=p;
36 }
37 return ans;
38 }
39
40 inline void exgcd(long long a,long long b,long long &x,long long &y)
41 {
42 b ? (exgcd(b,a%b,y,x),y=y-a/b*x):(x=1,y=0);
43 }
44
45 inline bool cmp(const pii a,const pii b)
46 {
47 return (a.first < b.first) || (a.first == b.first && a.second < b.second);
48 }
49
50 inline void work(long long x,long long y,long long mode)
51 {
52 if (mode == 1)
53 {
54 x%=p;
55 printf("%lld
",pow(x,y));
56 return;
57 }
58 if (mode == 2)
59 {
60 x%=p;
61 y%=p;
62 if (x == 0)
63 {
64 if (y == 0)
65 puts("0");
66 else
67 puts("Orz, I cannot find x!");
68 return;
69 }
70 long long a,b;
71 exgcd(x,p,a,b);
72 if (a < 0)
73 a+=p;
74 (a*=y)%=p;
75 printf("%lld
",a);
76 return;
77 }
78 x%=p;
79 y%=p;
80 if (x == 0)
81 {
82 if (y == 0)
83 puts("1");
84 else
85 puts("Orz, I cannot find x!");
86 return;
87 }
88 long long m=(long long)ceil(sqrt((double)p));
89 a[0].first=1;
90 a[0].second=0;
91 for (long long i=1;i<m;i++)
92 {
93 a[i].first=(a[i-1].first*x)%p;
94 a[i].second=i;
95 }
96 sort(a,a+m,cmp);
97 long long size=1;
98 for (long long i=1;i<m;i++)
99 if (a[i].first != a[i-1].first)
100 a[size++]=a[i];
101 long long wk=pow(pow(x,p-2),m);
102 long long tmp=y;
103 long long ans=-1;
104 for (long long i=0;i<m;i++)
105 {
106 long long now=lower_bound(a,a+m,make_pair(tmp,0LL))-a;
107 if (a[now].first == tmp)
108 {
109 ans=a[now].second+i*m;
110 break;
111 }
112 (tmp*=wk)%=p;
113 }
114 if (ans < 0)
115 puts("Orz, I cannot find x!");
116 else
117 printf("%lld
",ans);
118 }
119
120 int main()
121 {
122 long long _,k;
123 scanf("%lld%lld",&_,&k);
124 while (_--)
125 {
126 long long y,z;
127 scanf("%lld%lld%lld",&y,&z,&p);
128 work(y,z,k);
129 }
130 return 0;
131 }
View Code
bzoj2243
lct乱搞一下即可,刚开始看成树上数颜色瞬间吓尿了。。。
1 #include <cstdio>
2 #include <algorithm>
3 #include <bitset>
4
5 using namespace std;
6
7 #define maxn 100010
8
9 struct Node
10 {
11 int l,r,v,ans;
12 int lazy;
13 bool rot;
14 Node *s[2],*par;
15
16 Node()
17 {
18 lazy=-1;
19 }
20
21 inline bool S()
22 {
23 return this == par->s[1];
24 }
25 }t[maxn],null;
26
27 struct edge
28 {
29 int to;
30 edge *next;
31 }e[maxn<<1],*head[maxn];
32
33 int ne=0;
34 int q[maxn];
35 bitset <maxn> flag;
36
37 inline void add_edge(int from,int to)
38 {
39 e[ne].to=to;
40 e[ne].next=head[from];
41 head[from]=&e[ne++];
42 }
43
44 inline void bfs()
45 {
46 int op=0,cls=1;
47 flag.reset();
48 q[1]=1;
49 flag[1]=1;
50 while (op != cls)
51 {
52 int x=q[++op];
53 for (edge *p=head[x];p;p=p->next)
54 if (!flag[p->to])
55 {
56 t[p->to].par=&t[x];
57 q[++cls]=p->to;
58 flag[p->to]=1;
59 }
60 }
61 }
62
63 inline void _update(Node* now)
64 {
65 now->l=now->s[0] == &null ? now->v : now->s[0]->l;
66 now->r=now->s[1] == &null ? now->v : now->s[1]->r;
67 now->ans=now->s[0]->ans+now->s[1]->ans-(now->v == now->s[0]->r)-(now->v == now->s[1]->l)+1;
68 }
69
70 inline void _pushdown(Node* now)
71 {
72 if (now->rot)
73 {
74 swap(now->s[0],now->s[1]);
75 swap(now->s[0]->l,now->s[0]->r);
76 swap(now->s[1]->l,now->s[1]->r);
77 now->s[0]->rot^=1;
78 now->s[1]->rot^=1;
79 now->rot=0;
80 }
81 if (~now->lazy)
82 {
83 now->s[0]->v=now->s[0]->l=now->s[0]->r=now->lazy;
84 now->s[1]->v=now->s[1]->l=now->s[1]->r=now->lazy;
85 now->s[0]->lazy=now->lazy;
86 now->s[1]->lazy=now->lazy;
87 now->s[0]->ans=1;
88 now->s[1]->ans=1;
89 now->lazy=-1;
90 }
91 }
92
93 inline bool root(Node* now)
94 {
95 return now != now->par->s[0] && now != now->par->s[1];
96 }
97
98 inline void _rot(Node* now)
99 {
100 Node* p=now->par;
101 int l=now->S(),r=!l;
102 (p->s[l]=now->s[r])->par=p;
103 if (root(p))
104 now->par=p->par;
105 else
106 (p->par->s[p->S()]=now)->par=p->par;
107 (now->s[r]=p)->par=now;
108 null.s[0]=null.s[1]=null.par=&null;
109 null.v=null.l=null.r=null.lazy=-1;
110 null.ans=0;
111 _update(p);
112 _update(now);
113 }
114
115 void relax(Node* now)
116 {
117 if (!root(now))
118 relax(now->par);
119 _pushdown(now);
120 }
121
122 inline void _splay(Node* now)
123 {
124 relax(now);
125 while (!root(now))
126 {
127 if (root(now->par))
128 {
129 _rot(now);
130 return;
131 }
132 if (now->par->S() == now->S())
133 {
134 _rot(now->par);
135 _rot(now);
136 }
137 else
138 {
139 _rot(now);
140 _rot(now);
141 }
142 }
143 }
144
145 inline Node* access(Node* p)
146 {
147 Node* q=&null;
148 for (;p!=&null;q=p,p=p->par)
149 {
150 _splay(p);
151 _pushdown(p);
152 (p->s[1]=q)->par=p;
153 }
154 return q;
155 }
156
157 inline void set_root(Node* now)
158 {
159 access(now);
160 _splay(now);
161 now->rot^=1;
162 swap(now->l,now->r);
163 _pushdown(now);
164 }
165
166 inline void change(Node* p,Node* q,int col)
167 {
168 set_root(p);
169 access(q);
170 _splay(q);
171 q->lazy=q->v=q->l=q->r=col;
172 q->ans=1;
173 }
174
175 inline int query(Node* p,Node* q)
176 {
177 set_root(p);
178 access(q);
179 _splay(q);
180 _update(q);
181 return q->ans;
182 }
183
184 void travel(Node* now)
185 {
186 _pushdown(now);
187 printf("%d %d %d %d %d %d %d
",now-t,now->s[0]-t,now->s[1]-t,now->v,now->l,now->r,now->ans);
188 if (now->s[0] != &null)
189 travel(now->s[0]);
190 if (now->s[1] != &null)
191 travel(now->s[1]);
192 }
193
194 int main()
195 {
196 null.s[0]=null.s[1]=null.par=&null;
197 null.ans=0;
198 null.l=null.r=null.v=-1;
199 int n,m;
200 scanf("%d%d",&n,&m);
201 for (int i=1;i<=n;i++)
202 {
203 t[i].s[0]=t[i].s[1]=t[i].par=&null;
204 scanf("%d",&t[i].v);
205 t[i].l=t[i].r=t[i].v;
206 t[i].rot=0;
207 t[i].lazy=-1;
208 t[i].ans=1;
209 }
210 for (int i=1;i<n;i++)
211 {
212 int x,y;
213 scanf("%d%d",&x,&y);
214 add_edge(x,y);
215 add_edge(y,x);
216 }
217 bfs();
218 while (m--)
219 {
220 char s[10];
221 int x,y,z;
222 scanf("%s",s);
223 if (s[0] == 'C')
224 {
225 scanf("%d%d%d",&x,&y,&z);
226 change(&t[x],&t[y],z);
227 }
228 else
229 {
230 scanf("%d%d",&x,&y);
231 if (x == y)
232 puts("1");
233 else
234 printf("%d
",query(&t[x],&t[y]));
235 }
236 }
237 return 0;
238 }
View Code
bzoj2251
trie树上乱搞
1 #include <cstdio>
2
3 #define maxn 3010
4
5 struct Node
6 {
7 int size;
8 Node* s[2];
9 Node()
10 {
11 size=0;
12 }
13 }t[maxn*maxn],*root;
14
15 int n,ne=1;
16 int a[maxn];
17
18 inline void insert(int len)
19 {
20 Node* now=root;
21 for (int i=len;i<=n;i++)
22 {
23 if (now->s[a[i]] == NULL)
24 now->s[a[i]]=&t[ne++];
25 now=now->s[a[i]];
26 now->size++;
27 }
28 }
29
30 void dfs(Node* now)
31 {
32 if (now->size >= 2)
33 printf("%d
",now->size);
34 if (now->s[0] != NULL)
35 dfs(now->s[0]);
36 if (now->s[1] != NULL)
37 dfs(now->s[1]);
38 }
39
40 int main()
41 {
42 scanf("%d
",&n);
43 for (int i=1;i<=n;i++)
44 a[i]=getchar()-'0';
45 root=&t[0];
46 for (int i=1;i<=n;i++)
47 insert(i);
48 dfs(root);
49 return 0;
50 }
View Code
bzoj2252
从所有1的位置开始BFS
1 #include <cstdio>
2
3 #define maxn 1010
4
5 const int fx[]={0,1,0,-1};
6 const int fy[]={1,0,-1,0};
7
8 int map[maxn][maxn],ans[maxn][maxn],qx[maxn*maxn],qy[maxn*maxn];
9 bool flag[maxn][maxn];
10
11 int main()
12 {
13 int n,m;
14 scanf("%d%d",&n,&m);
15 int op=0,cls=0;
16 int cnt=0;
17 for (int i=1;i<=n;i++)
18 for (int j=1;j<=m;j++)
19 {
20 char ch;
21 while (ch=getchar(),ch != '0' && ch != '1');
22 map[i][j]=ch-'0';
23 if (map[i][j])
24 {
25 qx[++cls]=i;
26 qy[cls]=j;
27 flag[i][j]=1;
28 ans[i][j]=0;
29 cnt++;
30 }
31 }
32 for (int i=0;i<=m;i++)
33 flag[0][i]=flag[n+1][i]=1;
34 for (int i=0;i<=n;i++)
35 flag[i][0]=flag[i][m+1]=1;
36 while (op != cls && cnt != n*m)
37 {
38 int x=qx[++op],y=qy[op];
39 for (int i=0;i<4;i++)
40 {
41 int xx=x+fx[i];
42 int yy=y+fy[i];
43 if (!flag[xx][yy])
44 {
45 qx[++cls]=xx;
46 qy[cls]=yy;
47 ans[xx][yy]=ans[x][y]+1;
48 cnt++;
49 flag[xx][yy]=1;
50 }
51 }
52 }
53 for (int i=1;i<=n;i++)
54 {
55 for (int j=1;j<=m;j++)
56 printf("%d ",ans[i][j]);
57 puts("");
58 }
59 return 0;
60 }
View Code
bzoj2257
能给出的最少为选的瓶子容积的gcd(求证明),话说这道题之后我终于会用map了真高兴
1 #include <cstdio>
2 #include <map>
3 #include <algorithm>
4
5 using namespace std;
6
7 map <int,int> m;
8
9 #define maxn 1010
10
11 int main()
12 {
13 int n,k,ans=1;
14 scanf("%d%d",&n,&k);
15 for (int i=1;i<=n;i++)
16 {
17 int x;
18 scanf("%d",&x);
19 for (int j=1;j*j<=x;j++)
20 {
21 if (j*j == x)
22 {
23 m[j]++;
24 if (m[j] >= k)
25 ans=max(ans,j);
26 }
27 else
28 if (x%j == 0)
29 {
30 m[j]++;
31 m[x/j]++;
32 if (m[j] >= k)
33 ans=max(ans,j);
34 if (m[x/j] >= k)
35 ans=max(ans,x/j);
36 }
37 }
38 }
39 printf("%d
",ans);
40 return 0;
41 }
View Code
bzoj2258
写了一个非常蛋疼的splay维护hash,后来一看数据范围一口血啊。。。
1 #include <cstdio>
2 #include <cstring>
3
4 #define mod 27
5 #define maxn 50500
6
7 unsigned int hash[maxn];
8
9 struct Node
10 {
11 int size,size0,c,flag;
12 unsigned int v;
13 Node *par,*s[2];
14 Node()
15 {
16 size=size0=c=v=flag=0;
17 }
18 };
19
20 struct splay
21 {
22 Node t[maxn],null;
23 Node *root;
24 int ne;
25
26 splay()
27 {
28 null.s[0]=null.s[1]=null.par=&null;
29 t[0].s[0]=&null;t[0].s[1]=&t[1];t[0].par=&null;t[0].size=2;t[0].flag=1;t[0].size0=2;
30 t[1].s[0]=&null;t[1].s[1]=&null;t[1].par=&t[0];t[1].size=1;t[1].flag=1;t[1].size0=1;
31 root=&t[0];
32 ne=2;
33 }
34
35 void travel(Node* now)
36 {
37 if (now->s[0] != &null)
38 travel(now->s[0]);
39 printf("%c",now->c+'a'-1);
40 if (now->s[1] != &null)
41 travel(now->s[1]);
42 }
43
44 inline void _update(Node* now)
45 {
46 now->size=now->s[0]->size+now->s[1]->size+1;
47 now->size0=now->s[0]->size0+now->s[1]->size0+now->flag;
48 now->v=now->s[0]->v+now->c*hash[now->s[0]->size]+now->s[1]->v*hash[now->s[0]->size+1];
49 }
50
51 inline void _rot(Node* now,int l)
52 {
53 int r=!l;
54 Node* p=now->par;
55 Node* s=now->s[l];
56 (now->s[l]=s->s[r])->par=now;
57 (s->s[r]=now)->par=s;
58 s->par=p;
59 if (p != &null)
60 p->s[now == p->s[1]]=s;
61 _update(now);
62 _update(s);
63 }
64
65 inline void _splay(Node* now,Node* goal)
66 {
67 while(now->par != goal)
68 {
69 Node* p=now->par;
70 Node* g=p->par;
71 bool dp=now == p->s[1];
72 bool dg=p == g->s[1];
73 if (g == goal)
74 {
75 _rot(p,dp);
76 break;
77 }
78 if (dp == dg)
79 {
80 _rot(g,dg);
81 _rot(p,dp);
82 }
83 else
84 {
85 _rot(p,dp);
86 _rot(g,dg);
87 }
88 }
89 if (goal == &null)
90 root=now;
91 }
92
93 inline Node* _select(int v)
94 {
95 Node* now=root;
96 while (v)
97 {
98 if (now == &null)
99 return now;
100 if (now->s[0]->size+1 == v)
101 return now;
102 if (v <= now->s[0]->size)
103 now=now->s[0];
104 else
105 {
106 v-=now->s[0]->size+1;
107 now=now->s[1];
108 }
109 }
110 return &null;
111 }
112
113 inline Node* _find(int v)
114 {
115 Node* now=root;
116 while (v)
117 {
118 if (now == &null)
119 return now;
120 if (now->s[0]->size0+now->flag == v && now->flag)
121 return now;
122 if (v <= now->s[0]->size0)
123 now=now->s[0];
124 else
125 {
126 v-=now->s[0]->size0+now->flag;
127 now=now->s[1];
128 }
129 }
130 return &null;
131 }
132
133 inline void insert(int pos,int ch,int flag)
134 {
135 Node* p=_select(pos-1);
136 Node* q=_select(pos);
137 _splay(p,&null);
138 _splay(q,root);
139 Node* now=&t[ne++];
140 (q->s[0]=now)->par=q;
141 now->c=now->v=ch;
142 now->flag=now->size0=flag;
143 now->size=1;
144 now->s[0]=now->s[1]=&null;
145 _update(q);
146 _update(p);
147 }
148
149 inline bool check(int x,int y,int len)
150 {
151 Node *p,*q;
152 int r1,r2;
153 unsigned ans;
154 p=_find(x+1);
155 _splay(p,&null);
156 r1=p->s[0]->size;
157 r2=p->s[0]->size+len+1;
158 p=_select(r1);
159 q=_select(r2);
160 _splay(p,&null);
161 _splay(q,root);
162 ans=q->s[0]->v;
163 p=_find(y+1);
164 _splay(p,&null);
165 r1=p->s[0]->size;
166 r2=p->s[0]->size+len+1;
167 p=_select(r1);
168 q=_select(r2);
169 _splay(p,&null);
170 _splay(q,root);
171 return ans == q->s[0]->v;
172 }
173
174 inline int query(int x,int y)
175 {
176 int len=root->size;
177 Node* q=_find(y+1);
178 _splay(q,&null);
179 int l=1,r=len-q->s[0]->size,ans=0;
180 while (l < r)
181 {
182 int mid=(l+r)>>1;
183 if (check(x,y,mid))
184 {
185 ans=mid;
186 l=mid+1;
187 }
188 else
189 r=mid;
190 }
191 return ans;
192 }
193 }t;
194
195 char ch[maxn];
196
197 int main()
198 {
199 hash[0]=1;
200 for (int i=1;i<maxn;i++)
201 hash[i]=hash[i-1]*mod;
202 scanf("%s",ch);
203 int len=strlen(ch);
204 for (int i=0;i<len;i++)
205 t.insert(i+2,ch[i]-'a'+1,1);
206 int _,x,y;
207 char s[2];
208 scanf("%d",&_);
209 while (_--)
210 {
211 scanf("%s",s);
212 if (s[0] == 'Q')
213 {
214 scanf("%d%d",&x,&y);
215 if (x > y)
216 x^=y^=x^=y;
217 printf("%d
",t.query(x,y));
218 }
219 if (s[0] == 'I')
220 {
221 scanf("%s%d",s,&x);
222 if (x >= t.root->size-1)
223 x=t.root->size-1;
224 t.insert(x+1,s[0]-'a'+1,0);
225 }
226 }
227 }
View Code
bzoj2298
一个奇奇怪怪的类似DP的东西。。。
1 #include <cstdio>
2 #include <cstring>
3 #include <vector>
4 #include <algorithm>
5
6 using namespace std;
7
8 #define maxn 100010
9
10 vector <int> a[maxn];
11 vector <int> :: iterator it;
12 int sum[maxn],f[maxn];
13
14 inline void read(int &x)
15 {
16 x=0;
17 char ch;
18 while (ch=getchar(),ch > '9' || ch < '0');
19 x=ch-'0';
20 while (ch=getchar(),ch <= '9' && ch >= '0')
21 x=(x<<3)+x+x+ch-'0';
22 }
23
24 int main()
25 {
26 int n;
27 read(n);
28 for (int i=1;i<=n;i++)
29 {
30 int x,y;
31 read(x);
32 read(y);
33 if (x+y <= n-1)
34 a[x+1].push_back(n-y);
35 }
36 for (int i=1;i<=n;i++)
37 {
38 f[i]=max(f[i],f[i-1]);
39 for (it=a[i].begin();it!=a[i].end();it++)
40 sum[*it]++;
41 for (it=a[i].begin();it!=a[i].end();it++)
42 f[*it]=max(f[*it],f[i-1]+min(sum[*it],*it-i+1));
43 for (it=a[i].begin();it!=a[i].end();it++)
44 sum[*it]--;
45 }
46 printf("%d
",n-f[n]);
47 return 0;
48 }
View Code
bzoj2326
矩阵快速幂
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 10
5
6 typedef unsigned long long ull;
7
8 ull bit[20];
9 ull ans[maxn][maxn],sum[maxn][maxn],temp[maxn][maxn];
10
11 int main()
12 {
13 ull n,m;
14 bit[0]=1ll;
15 for (int i=1;i<=19;i++)
16 bit[i]=bit[i-1]*10;
17 scanf("%llu%llu",&n,&m);
18 ans[1][3]=1;
19 for (int i=1;i<=19;i++)
20 {
21 memset(sum,0,sizeof(sum));
22 sum[1][1]=bit[i]%m;
23 sum[2][1]=sum[2][2]=sum[3][1]=sum[3][2]=sum[3][3]=1;
24 ull num=0;
25 if (n < bit[i])
26 num=n-bit[i-1]+1;
27 else
28 num=bit[i]-bit[i-1];
29 for (;num;num>>=1)
30 {
31 if (num&1)
32 {
33 memset(temp,0,sizeof(temp));
34 for (int i=1;i<=3;i++)
35 for (int j=1;j<=3;j++)
36 for (int k=1;k<=3;k++)
37 (temp[i][j]+=ans[i][k]*sum[k][j])%=m;
38 for (int i=1;i<=3;i++)
39 for (int j=1;j<=3;j++)
40 ans[i][j]=temp[i][j];
41 }
42 memset(temp,0,sizeof(temp));
43 for (int i=1;i<=3;i++)
44 for (int j=1;j<=3;j++)
45 for (int k=1;k<=3;k++)
46 (temp[i][j]+=sum[i][k]*sum[k][j])%=m;
47 for (int i=1;i<=3;i++)
48 for (int j=1;j<=3;j++)
49 sum[i][j]=temp[i][j];
50 }
51 if (n < bit[i])
52 break;
53 }
54 printf("%llu
",ans[1][1]);
55 return 0;
56 }
View Code
bzoj2330
那叫什么来着。。。差分约束
1 #include <cstdio>
2 #include <cstring>
3
4 using namespace std;
5
6 const int maxn=100010;
7 const int maxm=300010;
8 const int inf=0x3f3f3f3f;
9
10 int n,m,ne=0;
11 int dist[maxn],q[maxn],inq[maxn],flag[maxn];
12
13 struct edge
14 {
15 edge *next;
16 int to,dist;
17 }e[maxm],*head[maxn];
18
19 inline bool spfa()
20 {
21 for (int i=1;i<=n;i++)
22 {
23 q[i]=i;
24 dist[i]=1;
25 flag[i]=1;
26 inq[i]=1;
27 }
28 int op=0,cls=n;
29 edge *p;
30 while (op != cls)
31 {
32 op++;
33 op%=maxn;
34 int x=q[op];
35 flag[x]=0;
36 for (p=head[x];p;p=p->next)
37 if (dist[x]+p->dist > dist[p->to])
38 {
39 dist[p->to]=dist[x]+p->dist;
40 if (!flag[p->to])
41 {
42 inq[p->to]++;
43 cls++;
44 cls%=maxn;
45 q[cls]=p->to;
46 flag[p->to]=1;
47 }
48 if (inq[p->to] > n)
49 return 0;
50 }
51 }
52 return 1;
53 }
54
55 inline void add_edge(int x,int y,int z)
56 {
57 e[ne].next=head[x];
58 e[ne].to=y;
59 e[ne].dist=z;
60 head[x]=&e[ne++];
61 }
62
63 int main()
64 {
65 scanf("%d%d",&n,&m);
66 int x,y,z;
67 while (m--)
68 {
69 scanf("%d%d%d",&x,&y,&z);
70 if (x == 1)
71 {
72 add_edge(y,z,0);
73 add_edge(z,y,0);
74 }
75 if (x == 2)
76 add_edge(y,z,1);
77 if (x == 3)
78 add_edge(z,y,0);
79 if (x == 4)
80 add_edge(z,y,1);
81 if (x == 5)
82 add_edge(y,z,0);
83 }
84 if (spfa())
85 {
86 long long ans=0;
87 for (int i=1;i<=n;i++)
88 ans+=(long long)dist[i];
89 printf("%lld
",ans);
90 }
91 else
92 printf("-1
");
93 return 0;
94 }
View Code
bzoj2338
以线段的中点的横坐标为第一关键字,纵坐标为第二关键字排序,然后找出所有中点相同的一对线段中面积最大的
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 1510
7
8 #ifdef unix
9 #define LL "%lld"
10 #else
11 #define LL "%I64d"
12 #endif
13
14 struct Node
15 {
16 long long f,t,x,y,len;
17 inline bool operator < (const Node b) const
18 {
19 if (x == b.x)
20 {
21 if (y == b.y)
22 return len < b.len;
23 return y < b.y;
24 }
25 return x < b.x;
26 }
27 }a[maxn*maxn];
28
29 inline long long sqr(long long x)
30 {
31 return x*x;
32 }
33
34 long long x[maxn],y[maxn];
35
36 int main()
37 {
38 long long n;
39 scanf(LL,&n);
40 for (long long i=1;i<=n;i++)
41 scanf(LL LL,&x[i],&y[i]);
42 long long cnt=0;
43 for (long long i=1;i<n;i++)
44 for (long long j=i+1;j<=n;j++)
45 {
46 cnt++;
47 a[cnt].f=i;
48 a[cnt].t=j;
49 a[cnt].x=x[i]+x[j];
50 a[cnt].y=y[i]+y[j];
51 a[cnt].len=sqr(x[i]-x[j])+sqr(y[i]-y[j]);
52 }
53 sort(a+1,a+cnt+1);
54 long long ans=0;
55 for (long long i=1;i<cnt;i++)
56 for (long long j=i+1;j<=cnt;j++)
57 if (a[i].x == a[j].x && a[i].y == a[j].y && a[i].len == a[j].len)
58 {
59 long long x1=x[a[j].f]-x[a[i].f];
60 long long x2=x[a[j].t]-x[a[i].f];
61 long long y1=y[a[j].f]-y[a[i].f];
62 long long y2=y[a[j].t]-y[a[i].f];
63 ans=max(ans,abs(x1*y2-x2*y1));
64 }
65 else
66 break;
67 printf(LL "
",ans);
68 return 0;
69 }
View Code
bzoj2342
manacher+set扫一遍,据说有O(n)的算法
1 #include <cstdio>
2 #include <algorithm>
3 #include <set>
4
5 using namespace std;
6
7 #define maxn 10000010
8
9 set <int> t;
10 set <int>::iterator it;
11
12 int n;
13 char a[maxn];
14 int p[maxn],pos[maxn];
15
16 inline int min(int a,int b)
17 {
18 return a < b ? a : b;
19 }
20
21 inline bool cmp(int a,int b)
22 {
23 return a-p[a] < b-p[b];
24 }
25
26 inline void doit()
27 {
28 int mx=0,id=0;
29 for (int i=1;i<n;i++)
30 {
31 if (mx > i)
32 p[i]=min(p[(id<<1)-i],mx-i);
33 else
34 p[i]=1;
35 for (;a[i+p[i]] == a[i-p[i]];p[i]++);
36 if (i+p[i] > mx)
37 {
38 mx=i+p[i];
39 id=i;
40 }
41 }
42 int size=0;
43 for (int i=2;i<=n;i+=2)
44 pos[++size]=i;
45 sort(pos+1,pos+size+1,cmp);
46 int now=1,ans=0;
47 for (int i=2;i<=n;i+=2)
48 {
49 while (now <= size && pos[now]-p[pos[now]] < i)
50 {
51 t.insert(pos[now]);
52 now++;
53 }
54 it=t.upper_bound(i+p[i]/2);
55 it--;
56 if (*it >= i && *it <= i+(p[i] >> 1))
57 ans=max(ans,(*it-i)*2);
58 }
59 printf("%d
",ans);
60 }
61
62 int main()
63 {
64 scanf("%d
",&n);
65 for (int i=1;i<=n;i++)
66 {
67 a[(i<<1)-1]=getchar();
68 a[(i<<1)]='#';
69 }
70 n=(n<<1)-1;
71 doit();
72 return 0;
73 }
View Code
bzoj2351
二维hash,矩阵模板的双倍经验,但是加强了数据,注意base的选取
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define base1 29
7 #define base2 31
8 #define maxn 1010
9
10 typedef unsigned int ull;
11
12 ull bit1[maxn],bit2[maxn];
13 ull a[maxn][maxn],san[maxn*maxn],map[maxn][maxn];
14
15 int main()
16 {
17 int m,n,l,r;
18 scanf("%d%d%d%d",&m,&n,&l,&r);
19 m^=n^=m^=n;
20 for (int i=1;i<=n;i++)
21 for (int j=1;j<=m;j++)
22 {
23 char ch;
24 while (ch=getchar(),ch != '0' && ch != '1');
25 map[i][j]=ch-'0';
26 if (map[i][j])
27 map[i][j]=19;
28 else
29 map[i][j]=17;
30 }
31 bit1[0]=bit2[0]=1;
32 for (int i=1;i<=n;i++)
33 {
34 bit1[i]=bit1[i-1]*base1;
35 bit2[i]=bit2[i-1]*base2;
36 }
37 for (int i=1;i<=n;i++)
38 {
39 ull now_hash=0;
40 for (int j=1;j<=r;j++)
41 now_hash=now_hash*base1+map[i][j];
42 a[i][r]=now_hash;
43 for (int j=r+1;j<=m;j++)
44 {
45 now_hash=now_hash*base1+map[i][j];
46 now_hash-=map[i][j-r]*bit1[r];
47 a[i][j]=now_hash;
48 }
49 }
50 int size=0;
51 for (int j=r+1;j<=m;j++)
52 {
53 ull now_hash=0;
54 for (int i=1;i<=l;i++)
55 now_hash=now_hash*base2+a[i][j];
56 san[++size]=now_hash;
57 for (int i=l+1;i<=n;i++)
58 {
59 now_hash=now_hash*base2+a[i][j];
60 now_hash-=a[i-l][j]*bit2[l];
61 san[++size]=now_hash;
62 }
63 }
64 sort(san+1,san+size+1);
65 size=unique(san+1,san+size+1)-san-1;
66 int q;
67 scanf("%d",&q);
68 while (q--)
69 {
70 for (int i=1;i<=l;i++)
71 for (int j=1;j<=r;j++)
72 {
73 char ch;
74 while (ch=getchar(),ch != '0' && ch != '1');
75 map[i][j]=ch-'0';
76 if (map[i][j])
77 map[i][j]=19;
78 else
79 map[i][j]=17;
80 }
81 ull hash=0;
82 for (int i=1;i<=l;i++)
83 {
84 ull now_hash=0;
85 for (int j=1;j<=r;j++)
86 now_hash=now_hash*base1+map[i][j];
87 hash=hash*base2+now_hash;
88 }
89 int pos=lower_bound(san+1,san+size+1,hash)-san;
90 if (san[pos] == hash)
91 puts("1");
92 else
93 puts("0");
94 }
95 return 0;
96 }
View Code
bzoj2424
当年一直以为是DP,然后费用流直接过了
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 1010
8 #define maxm 1000010
9 #define inf 0x3f3f3f3f
10 #define s 0
11 #define t maxn-1
12
13 struct edge
14 {
15 int to,flow,dist,cost;
16 edge *next,*part;
17 }e[maxm],*head[maxn],*prev[maxn];
18
19 int ne;
20 int q[maxn],d[maxn];
21 bool flag[maxn];
22
23 inline void add(int from,int to,int flow,int cost)
24 {
25 e[ne].to=to;
26 e[ne].flow=flow;
27 e[ne].cost=cost;
28 e[ne].next=head[from];
29 head[from]=&e[ne++];
30 }
31
32 inline void add_edge(int from,int to,int flow,int cost)
33 {
34 e[ne].part=&e[ne+1];
35 e[ne+1].part=&e[ne];
36 add(from,to,flow,cost);
37 add(to,from,0,-cost);
38 }
39
40 inline bool spfa()
41 {
42 memset(d,0x3f,sizeof(d));
43 memset(flag,0,sizeof(flag));
44 int op=0,cls=1;
45 q[1]=s;
46 d[s]=0;
47 flag[s]=1;
48 while (op != cls)
49 {
50 op=op == maxn-1 ? 0 : op+1;
51 int x=q[op];
52 for (edge *p=head[x];p;p=p->next)
53 if (p->flow && d[p->to] > d[x]+p->cost)
54 {
55 d[p->to]=d[x]+p->cost;
56 prev[p->to]=p->part;
57 if (!flag[p->to])
58 {
59 if (op != cls)
60 {
61 int now=op == maxn-1 ? 0 : op+1;
62 if (d[p->to] < d[q[now]])
63 {
64 q[op]=p->to;
65 op=op == 0 ? maxn-1 : op-1;
66 }
67 else
68 {
69 cls=cls == maxn-1 ? 0 : cls+1;
70 q[cls]=p->to;
71 }
72 }
73 else
74 {
75 cls=cls == maxn-1 ? 0 : cls+1;
76 q[cls]=p->to;
77 }
78 flag[p->to]=1;
79 }
80 }
81 flag[x]=0;
82 }
83 return d[t] != inf;
84 }
85
86 inline int agument()
87 {
88 int f=inf,ans=0;
89 for (edge *p=prev[t];p;p=prev[p->to])
90 f=min(f,p->part->flow);
91 for (edge *p=prev[t];p;p=prev[p->to])
92 {
93 p->flow+=f;
94 p->part->flow-=f;
95 ans+=p->part->cost*f;
96 }
97 return ans;
98 }
99
100 inline int min_cost()
101 {
102 int ans=0;
103 while (spfa())
104 ans+=agument();
105 return ans;
106 }
107
108 int main()
109 {
110 int n,m,v;
111 scanf("%d%d%d",&n,&m,&v);
112 for (int i=1;i<n;i++)
113 add_edge(i,i+1,v,m);
114 for (int i=1;i<=n;i++)
115 {
116 int x;
117 scanf("%d",&x);
118 add_edge(i,t,x,0);
119 }
120 for (int i=1;i<=n;i++)
121 {
122 int x;
123 scanf("%d",&x);
124 add_edge(s,i,inf,x);
125 }
126 printf("%d
",min_cost());
127 return 0;
128 }
View Code
bzoj2426
想了很久的网络流,最后发现是贪心。。。
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 55
7 #define maxm 50010
8 #define inf 0x3f3f3f3f
9
10 int c[maxn][maxm];
11 int a[maxm],h[maxn],d[maxm],pos[maxm];
12
13 inline void read(int &x)
14 {
15 char ch;
16 while (ch=getchar(),ch > '9' || ch < '0');
17 x=ch-'0';
18 while (ch=getchar(),ch <= '9' && ch >= '0')
19 x=(x<<3)+x+x+ch-'0';
20 }
21
22 inline bool cmp(const int a,const int b)
23 {
24 return d[a] < d[b];
25 }
26
27 int main()
28 {
29 int n,m,b,xx;
30 read(m);
31 read(b);
32 read(xx);
33 read(n);
34 for (int i=1;i<=m;i++)
35 read(a[i]);
36 for (int i=1;i<=n;i++)
37 read(h[i]);
38 for (int i=0;i<=n;i++)
39 for (int j=1;j<=m;j++)
40 read(c[i][j]);
41 int _min=inf,ans=0;
42 for (int i=1;i<=n;i++)
43 {
44 for (int j=1;j<=m;j++)
45 {
46 pos[j]=j;
47 d[j]=c[0][j]-c[i][j];
48 }
49 sort(pos+1,pos+m+1,cmp);
50 int rest=b,sum=0;
51 for (int j=1;j<=m;j++)
52 {
53 int now=pos[j];
54 if (a[now] <= rest)
55 {
56 rest-=a[now];
57 sum+=c[0][now]*a[now];
58 }
59 else
60 {
61 sum+=c[0][now]*rest;
62 rest=a[now]-rest;
63 sum+=c[i][now]*rest;
64 rest=0;
65 }
66 }
67 sum+=h[i];
68 if (sum < _min)
69 {
70 _min=sum;
71 ans=i;
72 }
73 }
74 printf("%d
",ans);
75 printf("%d
",_min+xx);
76 return 0;
77 }
View Code
bzoj2431
DP,f[i][j]表示放到i了,当前有j对逆序对的数列的个数
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 1010
7 #define mod 10000
8
9 int f[maxn][maxn],sum[maxn][maxn];
10
11 int main()
12 {
13 int n,k;
14 scanf("%d%d",&n,&k);
15 for (int i=1;i<=n;i++)
16 {
17 f[i][1]=sum[i][1]=1;
18 for (int j=2;j<=k+1;j++)
19 {
20 f[i][j]=(sum[i-1][j]-sum[i-1][max(j-i,0)]+mod)%mod;
21 sum[i][j]=(sum[i][j-1]+f[i][j])%mod;
22 }
23 }
24 printf("%d
",f[n][k+1]);
25 return 0;
26 }
View Code
bzoj2435
树形DFS
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 1000010
7
8 struct edge
9 {
10 int to,dist;
11 edge *next;
12 }e[maxn<<1],*head[maxn];
13
14 int ne=0;
15 int fa[maxn],w[maxn],size[maxn];
16
17 inline void read(int &x)
18 {
19 char ch;
20 while (ch=getchar(),ch > '9' || ch < '0');
21 x=ch-'0';
22 while (ch=getchar(),ch <= '9' && ch >= '0')
23 x=(x<<3)+x+x+ch-'0';
24 }
25
26 inline void add_edge(int from,int to,int dist)
27 {
28 e[ne].to=to;
29 e[ne].dist=dist;
30 e[ne].next=head[from];
31 head[from]=&e[ne++];
32 }
33
34 void dfs(int now)
35 {
36 size[now]=1;
37 for (edge *p=head[now];p;p=p->next)
38 if (p->to != fa[now])
39 {
40 fa[p->to]=now;
41 w[p->to]=p->dist;
42 dfs(p->to);
43 size[now]+=size[p->to];
44 }
45 }
46
47 int main()
48 {
49 int n;
50 read(n);
51 for (int i=1;i<n;i++)
52 {
53 int x,y,z;
54 read(x);
55 read(y);
56 read(z);
57 add_edge(x,y,z);
58 add_edge(y,x,z);
59 }
60 dfs(1);
61 long long ans=0;
62 for (int i=2;i<=n;i++)
63 ans+=(long long)abs(n-size[i]*2)*w[i];
64 printf("%lld
",ans);
65 return 0;
66 }
View Code
bzoj2436
让我想这个DP肯定想不出来。。。题读错了好几遍。。。具体题解百度吧
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 410
8 #define inf 0x3f3f3f3f
9
10 int b[maxn];
11 int f[maxn][maxn],g[maxn][maxn],ans[maxn][maxn],num[maxn][maxn];
12 int l[maxn],r[maxn];
13
14 inline int max(int a,int b)
15 {
16 return a > b ? a : b;
17 }
18
19 inline int min(int a,int b)
20 {
21 return a < b ? a : b;
22 }
23
24 int main()
25 {
26 int n;
27 int size=0;
28 scanf("%d",&n);
29 for (int i=1;i<=n;i++)
30 {
31 scanf("%d%d",&l[i],&r[i]);
32 r[i]+=l[i];
33 b[++size]=l[i];
34 b[++size]=r[i];
35 }
36 sort(b+1,b+size+1);
37 size=unique(b+1,b+size+1)-b-1;
38 for (int i=1;i<=n;i++)
39 {
40 l[i]=lower_bound(b+1,b+size+1,l[i])-b;
41 r[i]=lower_bound(b+1,b+size+1,r[i])-b;
42 }
43 for (int i=1;i<=size;i++)
44 for (int j=i;j<=size;j++)
45 for (int k=1;k<=n;k++)
46 if (l[k] >= i && r[k] <= j)
47 num[i][j]++;
48 for (int i=0;i<=size+1;i++)
49 for (int j=0;j<=size+1;j++)
50 f[i][j]=g[i][j]=-inf;
51 f[0][0]=0;
52 for (int i=1;i<=size;i++)
53 for (int j=i;j>=0;j--)
54 {
55 f[i][j]=f[i][j+1];
56 for (int k=0;k<i;k++)
57 {
58 f[i][j]=max(f[i][j],f[k][j]+num[k][i]);
59 if (j >= num[k][i])
60 f[i][j]=max(f[i][j],f[k][j-num[k][i]]);
61 }
62 }
63 g[size+1][0]=0;
64 for (int i=size;i;i--)
65 for (int j=size-i+1;j>=0;j--)
66 {
67 g[i][j]=g[i][j+1];
68 for (int k=i+1;k<=size+1;k++)
69 {
70 g[i][j]=max(g[i][j],g[k][j]+num[i][k]);
71 if (j >= num[i][k])
72 g[i][j]=max(g[i][j],g[k][j-num[i][k]]);
73 }
74 }
75 for (int i=1;i<=size;i++)
76 for (int j=i;j<=size;j++)
77 for (int x=0;x<=i;x++)
78 for (int y=0;y<=size-j+1;y++)
79 if (x+y <= n)
80 {
81 int now=min(x+y+num[i][j],f[i][x]+g[j][y]);
82 if (ans[i][j] < now)
83 ans[i][j]=now;
84 else
85 break;
86 }
87 else
88 break;
89 int now=0;
90 for (int i=1;i<=n;i++)
91 now=max(now,min(i,f[size][i]));
92 printf("%d
",now);
93 for (int i=1;i<=n;i++)
94 {
95 now=0;
96 for (int j=1;j<=l[i];j++)
97 for (int k=r[i];k<=size;k++)
98 now=max(now,ans[j][k]);
99 printf("%d
",now);
100 }
101 return 0;
102 }
View Code
bzoj2457
据说可以排序之后贪心,表示只能理解排序之后DP。。。
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 200010
7
8 typedef pair <int,int> pii;
9
10 pii a[maxn];
11 int _max[maxn],_min[maxn];
12 int f[maxn][2];
13
14 inline void read(int &x)
15 {
16 char ch;
17 bool flag=0;
18 while (ch=getchar(),(ch > '9' || ch < '0') && (ch != '-'));
19 if (ch == '-')
20 flag=1;
21 else
22 x=ch-'0';
23 while (ch=getchar(),ch <= '9' && ch >= '0')
24 x=(x<<3)+x+x+ch-'0';
25 if (flag)
26 x=-x;
27 }
28
29 inline bool cmp(const pii a,const pii b)
30 {
31 return (a.first < b.first) || (a.first == b.first && a.second < b.second);
32 }
33
34 int main()
35 {
36 // freopen("1.in","r",stdin);
37 // freopen("1.out","w",stdout);
38 int n;
39 read(n);
40 for (int i=1;i<=n;i++)
41 {
42 read(a[i].first);
43 a[i].second=i;
44 }
45 sort(a+1,a+n+1,cmp);
46 a[0].first=a[1].first;
47 int cnt=1;
48 _min[cnt]=a[1].second;
49 for (int i=1;i<=n;i++)
50 if (a[i].first != a[i-1].first)
51 {
52 _max[cnt]=a[i-1].second;
53 cnt++;
54 _min[cnt]=a[i].second;
55 }
56 _max[cnt]=a[n].second;
57 f[1][0]=f[1][1]=1;
58 for (int i=2;i<=cnt;i++)
59 {
60 if (_min[i] < _max[i-1])
61 f[i][0]=min(f[i-1][0]+1,f[i-1][1]);
62 else
63 f[i][0]=min(f[i-1][0],f[i-1][1]);
64 if (_max[i] > _min[i-1])
65 f[i][1]=min(f[i-1][0],f[i-1][1])+1;
66 else
67 f[i][1]=min(f[i-1][0]+1,f[i-1][1]);
68 }
69 printf("%d
",min(f[cnt][0],f[cnt][1]));
70 return 0;
71 }
View Code
bzoj2462
二维hash,据说可以KMP,又据说答案全是1可以过
#include <cstdio>
#include <algorithm>
using namespace std;
#define base1 29
#define base2 31
#define maxn 1010
typedef unsigned int ull;
ull bit1[maxn],bit2[maxn];
ull a[maxn][maxn],san[maxn*maxn],map[maxn][maxn];
int main()
{
int m,n,l,r;
scanf("%d%d%d%d",&m,&n,&l,&r);
m^=n^=m^=n;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
char ch;
while (ch=getchar(),ch != '0' && ch != '1');
map[i][j]=ch-'0';
if (map[i][j])
map[i][j]=19;
else
map[i][j]=17;
}
bit1[0]=bit2[0]=1;
for (int i=1;i<=n;i++)
{
bit1[i]=bit1[i-1]*base1;
bit2[i]=bit2[i-1]*base2;
}
for (int i=1;i<=n;i++)
{
ull now_hash=0;
for (int j=1;j<=r;j++)
now_hash=now_hash*base1+map[i][j];
a[i][r]=now_hash;
for (int j=r+1;j<=m;j++)
{
now_hash=now_hash*base1+map[i][j];
now_hash-=map[i][j-r]*bit1[r];
a[i][j]=now_hash;
}
}
int size=0;
for (int j=r+1;j<=m;j++)
{
ull now_hash=0;
for (int i=1;i<=l;i++)
now_hash=now_hash*base2+a[i][j];
san[++size]=now_hash;
for (int i=l+1;i<=n;i++)
{
now_hash=now_hash*base2+a[i][j];
now_hash-=a[i-l][j]*bit2[l];
san[++size]=now_hash;
}
}
sort(san+1,san+size+1);
size=unique(san+1,san+size+1)-san-1;
int q;
scanf("%d",&q);
while (q--)
{
for (int i=1;i<=l;i++)
for (int j=1;j<=r;j++)
{
char ch;
while (ch=getchar(),ch != '0' && ch != '1');
map[i][j]=ch-'0';
if (map[i][j])
map[i][j]=19;
else
map[i][j]=17;
}
ull hash=0;
for (int i=1;i<=l;i++)
{
ull now_hash=0;
for (int j=1;j<=r;j++)
now_hash=now_hash*base1+map[i][j];
hash=hash*base2+now_hash;
}
int pos=lower_bound(san+1,san+size+1,hash)-san;
if (san[pos] == hash)
puts("1");
else
puts("0");
}
return 0;
}
View Code
bzoj2463
我还能说什么好呢。。。这道题。。。
1 #include <cstdio>
2
3 int main()
4 {
5 int n;
6 while (~scanf("%d",&n))
7 {
8 if (!n)
9 break;
10 if (n&1)
11 puts("Bob");
12 else
13 puts("Alice");
14 }
15 return 0;
16 }
View Code
bzoj2464
要不要那么裸的spfa。。。当年拿来练slf优化用的,手写双端循环队列的寂寞。。。
1 #include <cstdio>
2 #include <cstring>
3
4 #define maxn 2500010
5 #define maxm 5000010
6
7 struct edge
8 {
9 int to,dist;
10 edge *next;
11 }e[maxm],*head[maxn];
12
13 int ne=0;
14 int pos[510][510];
15 int q[maxn],d[maxn];
16 bool map[maxn],flag[maxn];
17
18 inline void add_edge(int from,int to,int dist)
19 {
20 e[ne].to=to;
21 e[ne].dist=dist;
22 e[ne].next=head[from];
23 head[from]=&e[ne++];
24 }
25
26 inline int spfa(int s,int t)
27 {
28 int op=0,cls=1;
29 memset(d,0x3f,sizeof(d));
30 memset(flag,0,sizeof(flag));
31 q[1]=s;
32 d[s]=0;
33 flag[s]=1;
34 while (op != cls)
35 {
36 op=op == maxn-1 ? 0 : op+1;
37 int x=q[op];
38 flag[x]=0;
39 for (edge *p=head[x];p;p=p->next)
40 {
41 if (d[x]+p->dist < d[p->to])
42 {
43 d[p->to]=d[x]+p->dist;
44 if (!flag[p->to])
45 {
46 if (op != cls)
47 {
48 int now=op == maxn-1 ? 0 : op+1;
49 if (d[p->to] < d[q[now]])
50 {
51 q[op]=p->to;
52 op=op == 0 ? maxn-1 : op-1;
53 }
54 else
55 {
56 cls=cls == maxn-1 ? 0 : cls+1;
57 q[cls]=p->to;
58 }
59 }
60 else
61 {
62 cls=cls == maxn-1 ? 0 : cls+1;
63 q[cls]=p->to;
64 }
65 flag[p->to]=1;
66 }
67 }
68 }
69 }
70 return d[t];
71 }
72
73 int main()
74 {
75 int n,m;
76 while (1)
77 {
78 scanf("%d%d",&n,&m);
79 if (!n && !m)
80 break;
81 for (int i=1;i<=n;i++)
82 for (int j=1;j<=m;j++)
83 pos[i][j]=(i-1)*m+j;
84 for (int i=1;i<=n;i++)
85 for (int j=1;j<=m;j++)
86 {
87 char ch;
88 while (ch=getchar(),ch != '@' && ch != '#');
89 if (ch == '@')
90 map[pos[i][j]]=1;
91 else
92 map[pos[i][j]]=0;
93 }
94 ne=0;
95 memset(head,0x0,sizeof(head));
96 for (int i=1;i<=n;i++)
97 for (int j=1;j<=m;j++)
98 {
99 if (i != 1)
100 add_edge(pos[i][j],pos[i-1][j],map[pos[i][j]] != map[pos[i-1][j]]);
101 if (i != n)
102 add_edge(pos[i][j],pos[i+1][j],map[pos[i][j]] != map[pos[i+1][j]]);
103 if (j != 1)
104 add_edge(pos[i][j],pos[i][j-1],map[pos[i][j]] != map[pos[i][j-1]]);
105 if (j != m)
106 add_edge(pos[i][j],pos[i][j+1],map[pos[i][j]] != map[pos[i][j+1]]);
107 }
108 int sx,sy,tx,ty;
109 scanf("%d%d%d%d",&sx,&sy,&tx,&ty);
110 sx++;
111 sy++;
112 tx++;
113 ty++;
114 printf("%d
",spfa(pos[sx][sy],pos[tx][ty]));
115 }
116 return 0;
117 }
View Code
bzoj2465
太水了不想说了。。。
1 #include <cstdio>
2 #include <algorithm>
3
4 using namespace std;
5
6 #define maxn 210
7
8 int a[maxn];
9
10 struct xxx
11 {
12 int v,val;
13 inline bool operator < (const xxx b) const
14 {
15 return val > b.val;
16 }
17 }b[maxn];
18
19 inline bool cmp(const int a,const int b)
20 {
21 return a > b;
22 }
23
24 int main()
25 {
26 int n,m;
27 while (1)
28 {
29 scanf("%d%d",&n,&m);
30 if (n == 0 && m == 0)
31 break;
32 for (int i=1;i<=n;i++)
33 scanf("%d",&a[i]);
34 for (int i=1;i<=m;i++)
35 scanf("%d%d",&b[i].v,&b[i].val);
36 sort(a+1,a+n+1,cmp);
37 sort(b+1,b+m+1);
38 int nowa=1,nowb=1,ans=0,sum=0;
39 while (nowb <= m)
40 {
41 while (b[nowb].val < a[nowa] && nowa <= n)
42 nowa++;
43 if (nowa == n+1)
44 break;
45 while (b[nowb].v && nowa <= n)
46 {
47 sum++;
48 ans+=a[nowa];
49 b[nowb].v--;
50 nowa++;
51 }
52 if (nowa == n+1)
53 break;
54 nowb++;
55 }
56 printf("%d %d
",sum,ans);
57 }
58 return 0;
59 }
View Code
bzoj2467
推公式
1 #include <cstdio>
2
3 int main()
4 {
5 int _;
6 scanf("%d",&_);
7 while (_--)
8 {
9 int n,ans=4;
10 scanf("%d",&n);
11 ans*=n;
12 for (int i=1;i<n;i++)
13 (ans*=5)%=2007;
14 printf("%d
",ans);
15 }
16 return 0;
17 }
View Code
bzoj2535
对于这种双倍经验我能说什么呢?
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 2010
8 #define maxm 10010
9
10 struct edge
11 {
12 int to;
13 edge *next;
14 }e[maxm],*head[maxn];
15
16 int ne=0;
17 int cnt=0;
18 int q[maxn],ans[maxn],in[maxn];
19 pair <int,int> a[maxn];
20 bool check[maxn][maxn];
21 bool flag[maxn];
22
23 inline void add_edge(int from,int to)
24 {
25 e[ne].to=to;
26 e[ne].next=head[from];
27 head[from]=&e[ne++];
28 }
29
30 void dfs(int x)
31 {
32 flag[x]=1;
33 for (edge *p=head[x];p;p=p->next)
34 if (!flag[p->to])
35 dfs(p->to);
36 q[++cnt]=x;
37 }
38
39 void dfs(int now,int x)
40 {
41 flag[x]=1;
42 check[now][x]=1;
43 for (edge *p=head[x];p;p=p->next)
44 if (!flag[p->to])
45 dfs(now,p->to);
46 }
47
48 int main()
49 {
50 int n,m;
51 scanf("%d%d",&n,&m);
52 int x,y;
53 for (int i=1;i<=n;i++)
54 {
55 scanf("%d",&a[i].first);
56 a[i].second=i;
57 }
58 for (int i=1;i<=m;i++)
59 {
60 scanf("%d%d",&x,&y);
61 add_edge(y,x);
62 }
63 for (int i=1;i<=n;i++)
64 if (!flag[i])
65 dfs(i);
66 for (int i=n;i;i--)
67 {
68 int x=q[i];
69 for (edge *p=head[x];p;p=p->next)
70 a[p->to].first=min(a[p->to].first,a[x].first-1);
71 }
72 sort(a+1,a+n+1);
73 for (int i=1;i<=n;i++)
74 {
75 memset(flag,0,sizeof(flag));
76 dfs(i,i);
77 printf("%d ",a[i].second);
78 }
79 puts("");
80 for (int i=1;i<=n;i++)
81 {
82 int now=n;
83 for (int j=n;j;j--)
84 if (!check[i][a[j].second] && a[j].first >= now)
85 now--;
86 else
87 if (a[j].first < now)
88 break;
89 printf("%d ",now);
90 }
91 return 0;
92 }
View Code
bzoj2539
裸费用流。。。
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define maxn 1100
8 #define maxm 1000010
9 #define inf 0x3f3f3f3f
10 #define s 0
11 #define t maxn-1
12
13 struct edge
14 {
15 int to,flow,cost;
16 edge *next,*part;
17 }e[maxm],*head[maxn],*prev[maxn];
18
19 int ne=0;
20 int q[maxn],d[maxn];
21 bool flag[maxn];
22
23 inline void add(int from,int to,int flow,int cost)
24 {
25 e[ne].to=to;
26 e[ne].flow=flow;
27 e[ne].cost=cost;
28 e[ne].next=head[from];
29 head[from]=&e[ne++];
30 }
31
32 inline void add_edge(int from,int to,int flow,int cost)
33 {
34 e[ne].part=&e[ne+1];
35 e[ne+1].part=&e[ne];
36 add(from,to,flow,cost);
37 add(to,from,0,-cost);
38 }
39
40
41 inline bool spfa()
42 {
43 memset(d,0x80,sizeof(d));
44 memset(flag,0,sizeof(flag));
45 int op=0,cls=1;
46 q[1]=s;
47 d[s]=0;
48 flag[s]=1;
49 while (op != cls)
50 {
51 op=op == maxn-1 ? 0 : op+1;
52 int x=q[op];
53 for (edge *p=head[x];p;p=p->next)
54 if (p->flow && d[p->to] < d[x]+p->cost)
55 {
56 d[p->to]=d[x]+p->cost;
57 prev[p->to]=p->part;
58 if (!flag[p->to])
59 {
60 if (op != cls)
61 {
62 int now=op == maxn-1 ? 0 : op+1;
63 if (d[p->to] > d[q[now]])
64 {
65 q[op]=p->to;
66 op=op == 0 ? maxn-1 : op-1;
67 }
68 else
69 {
70 cls=cls == maxn-1 ? 0 : cls+1;
71 q[cls]=p->to;
72 }
73 }
74 else
75 {
76 cls=cls == maxn-1 ? 0 : cls+1;
77 q[cls]=p->to;
78 }
79 flag[p->to]=1;
80 }
81 }
82 flag[x]=0;
83 }
84 return d[t] > -inf;
85 }
86
87 inline int agument()
88 {
89 int f=inf,ans=0;
90 for (edge *p=prev[t];p;p=prev[p->to])
91 f=min(f,p->part->flow);
92 for (edge *p=prev[t];p;p=prev[p->to])
93 {
94 p->flow+=f;
95 p->part->flow-=f;
96 ans+=p->part->cost*f;
97 }
98 return ans;
99 }
100
101 inline int max_cost()
102 {
103 int ans=0;
104 while (spfa())
105 ans+=agument();
106 return ans;
107 }
108
109 int range,n;
110 int x[maxn],y[maxn],l[maxn];
111 char name[maxn][30];
112 int map[maxn][maxn];
113
114 inline int sqr(int x)
115 {
116 return x*x;
117 }
118
119 inline bool check(int a,int b)
120 {
121 int d=sqr(x[a]-x[b])+sqr(y[a]-y[b]);
122 if (d > range)
123 return 0;
124 if (x[a] == x[b])
125 {
126 if (y[a] > y[b])
127 swap(a,b);
128 for (int i=1;i<=2*n;i++)
129 if (i != a && i != b)
130 if (x[i] == x[a] && y[i] > y[a] && y[i] < y[b])
131 return 0;
132 return 1;
133 }
134 if (x[a] > x[b])
135 swap(a,b);
136 for (int i=1;i<=2*n;i++)
137 if (i != a && i != b)
138 if (x[i] > x[a] && x[i] < x[b])
139 if ((y[b]-y[i])*(x[i]-x[a]) == (y[i]-y[a])*(x[b]-x[i]))
140 return 0;
141 return 1;
142 }
143
144 inline bool cmp(int a,int b)
145 {
146 if (l[a] != l[b])
147 return 0;
148 for (int i=0;i<l[a];i++)
149 if (name[a][i] != name[b][i])
150 return 0;
151 return 1;
152 }
153
154 inline bool cmp(int a,char *now)
155 {
156 int len=strlen(now);
157 if (len != l[a])
158 return 0;
159 for (int i=0;i<len;i++)
160 if (name[a][i] != now[i])
161 return 0;
162 return 1;
163 }
164
165 int main()
166 {
167 scanf("%d",&range);
168 range*=range;
169 scanf("%d",&n);
170 for (int i=1;i<=2*n;i++)
171 {
172 scanf("%d%d%s",&x[i],&y[i],name[i]);
173 l[i]=strlen(name[i]);
174 for (int j=0;j<l[i];j++)
175 if (name[i][j] >= 'A' && name[i][j] <= 'Z')
176 name[i][j]+=32;
177 }
178 char s1[maxn],s2[maxn];
179 while (1)
180 {
181 scanf("%s",s1);
182 if (s1[0] == 'E' && s1[1] == 'n' && s1[2] == 'd' && s1[3] == '