A:有字符串A和B,若A和B匹配,那么字符集存在一个单射,使得F(A)=B。现在给出长度为n的序列和长度为m的序列,问第一个序列中有多少子串与第二个序列匹配。

回想kmp的过程,事实上,只要“等于号”满足传递性就可以进行匹配。

看代码就知道了。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=1E6+5;
  4 int n,m,a[maxn],b[maxn],f[maxn],last[maxn],lastA[maxn],bucket[maxn],ans[maxn];
  5 inline int read()
  6 {
  7     char ch=getchar();
  8     while(!isdigit(ch))ch=getchar();
  9     int sum=ch-'0';ch=getchar();
 10     while(isdigit(ch)){sum=sum*10+ch-'0';ch=getchar();}
 11     return sum;
 12 }
 13 int G[55];
 14 inline void write(int x,const char&ch)
 15 {
 16     int g=0;
 17     do{G[++g]=x%10;x/=10;}while(x);
 18     for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar(ch);
 19 }
 20 inline bool match(int x,int y)
 21 {
 22     if(last[y]>=x||last[y]==0)
 23     {
 24         if(last[x]==0)
 25             return true;
 26         return false;
 27     }
 28     else
 29     {
 30         if(b[x-last[y]]==b[x])
 31             return true;
 32         return false;
 33     }
 34 }
 35 inline bool matchA(int x,int y)
 36 {
 37     if(lastA[y]>=x||lastA[y]==0)
 38     {
 39         if(last[x]==0)
 40             return true;
 41         return false;
 42     }
 43     else
 44     {
 45         if(b[x-lastA[y]]==b[x])
 46             return true;
 47         return false;
 48     }
 49 }
 50 inline void solve()
 51 {
 52     memset(f,0,sizeof(f));
 53     memset(last,0,sizeof(last));
 54     memset(lastA,0,sizeof(lastA));
 55     memset(bucket,0,sizeof(bucket));
 56     n=read(),m=read();
 57     for(int i=1;i<=n;++i)
 58     {
 59         a[i]=read();
 60         lastA[i]=bucket[a[i]];
 61         bucket[a[i]]=i;
 62     }
 63     memset(bucket,0,sizeof(bucket));
 64     for(int i=1;i<=m;++i)
 65     {
 66         b[i]=read();
 67         last[i]=bucket[b[i]];
 68         bucket[b[i]]=i;
 69     }
 70     for(int i=1;i<=m;++i)
 71         if(last[i])
 72             last[i]=i-last[i];
 73     for(int i=1;i<=n;++i)
 74         if(lastA[i])
 75             lastA[i]=i-lastA[i];
 76     int pos=0;
 77     for(int i=2;i<=m;++i)
 78     {
 79         while(pos&&!match(pos+1,i))
 80             pos=f[pos];
 81         if(match(pos+1,i))
 82             ++pos;
 83         f[i]=pos;
 84     }
 85     int tot=0;
 86     pos=0;
 87     for(int i=1;i<=n;++i)
 88     {
 89         while(pos&&!matchA(pos+1,i))
 90             pos=f[pos];
 91         if(matchA(pos+1,i))
 92             ++pos;
 93         if(pos==m)
 94         {
 95             ans[++tot]=i-m+1;
 96             pos=f[pos];
 97         }
 98     }
 99     write(tot,'\n');
100     for(int i=1;i<=tot;++i)
101         write(ans[i],' ');
102     putchar('\n');
103 }
104 int main()
105 {
106 //    freopen("xiz.in","r",stdin);
107 //    freopen("xiz.out","w",stdout);
108     ios::sync_with_stdio(false);
109     int T=read(),useless=read();
110     while(T--)
111         solve();
112     return 0;
113 }
View Code

B:n个同心圆,每个同心圆上选择一个点,问这些点组成的凸包面积最大为多少。n<=8。

一个三角形面积计算可以看成是a*b*sin/2,这里不用叉积,方便拉格朗日数乘,没什么好说的。

可以看csl的。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long double ld;
 4 const ld pi=acos(-1);
 5 const ld eps=1E-8;
 6 int n,m,p[55];
 7 ld ans,a[55],r[55],theta[55];
 8 inline bool cmp(ld x,ld y)
 9 {
10     return x>y;
11 }
12 inline ld get(ld lambda)
13 {
14     ld tot=0,sum=0;
15     r[m+1]=r[1];
16     for(int i=1;i<=m;++i)
17     {
18         theta[i]=acos(lambda/(r[i]*r[i+1]));
19         tot+=theta[i];
20     }
21     return tot;
22 }
23 inline void solve()
24 {
25     for(int i=1;i<=m;++i)
26         r[i]=a[p[i]];
27     ld L=-a[n]*a[n-1],R=a[n]*a[n-1],mid;
28     while(abs(L-R)>eps)
29     {
30         mid=(L+R)/2;
31         if(get(mid)>=2*pi)
32             L=mid;
33         else
34             R=mid;
35     }
36     if(abs(get(mid)-2*pi)<=0.000001)
37     {
38         r[m+1]=r[1];
39         ld sum=0;
40         for(int i=1;i<=m;++i)
41             sum+=r[i]*r[i+1]*sin(theta[i]);
42         ans=max(ans,sum);
43     }
44 }
45 int main()
46 {
47 //    freopen("yja.in","r",stdin);
48 //    freopen("yja.out","w",stdout);
49     ios::sync_with_stdio(false);
50     cin>>n;
51     for(int i=1;i<=n;++i)
52         cin>>a[i];
53     sort(a+1,a+n+1,cmp);
54     for(m=3;m<=n;++m)
55     {
56         for(int i=1;i<=m;++i)
57             p[i]=i;
58         do
59         {
60             solve();
61         }while(next_permutation(p+1,p+m+1));
62     }
63     cout<<fixed<<setprecision(8)<<ans/2<<endl;
64     return 0;
65 }
66 /*
67 276500.1521568
68 8
69 100 200 300 400 500 600 700 1000
70 8
71 1 100 300 400 500 600 700 1000
72 8
73 1 1 1 1 1000 1000 1000 1000
74 */
View Code

C:区间排序(有升序,也有降序),区间求和。

这是std的代码,不知为何有这么长。

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <cctype>
  6 #include <climits>
  7 #include <cassert>
  8 #include <ctime>
  9 #include <iostream>
 10 #include <fstream>
 11 #include <algorithm>
 12 #include <functional>
 13 #include <string>
 14 
 15 #define x first
 16 #define y second
 17 #define MP std::make_pair
 18 #define VAL(x) #x " = " << x << " "
 19 #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
 20 #ifdef __linux__
 21 #define getchar getchar_unlocked
 22 #define putchar putchar_unlocked
 23 #endif
 24 
 25 typedef long long LL;
 26 typedef std::pair<int, int> Pii;
 27 
 28 const int oo = 0x3f3f3f3f;
 29 
 30 template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, true : false; }
 31 template<typename T> inline bool chkmin(T &a, T b) { return a > b ? a = b, true : false; }
 32 std::string procStatus()
 33 {
 34     std::ifstream t("/proc/self/status");
 35     return std::string(std::istreambuf_iterator<char>(t), std::istreambuf_iterator<char>());
 36 }
 37 template<typename T> T read(T &x)
 38 {
 39     int f = 1;
 40     char ch = getchar();
 41     for (; !isdigit(ch); ch = getchar())
 42         if (ch == '-')
 43             f = -1;
 44     for (x = 0; isdigit(ch); ch = getchar())
 45         x = 10 * x + ch - '0';
 46     return x *= f;
 47 }
 48 template<typename T> void write(T x)
 49 {
 50     if (x == 0) {
 51         putchar('0');
 52         return;
 53     }
 54     if (x < 0) {
 55         putchar('-');
 56         x = -x;
 57     }
 58     static char s[20];
 59     int top = 0;
 60     for (; x; x /= 10)
 61         s[++top] = x % 10 + '0';
 62     while (top)
 63         putchar(s[top--]);
 64 }
 65 
 66 
 67 typedef long double LD;
 68 
 69 const int MAXN = 2e5 + 5, MAXM = 2e5 + 5;
 70 
 71 int N, M;
 72 int A0[MAXN];
 73 LD A[MAXN];
 74 int id[MAXN], begin[MAXN], end[MAXN];
 75 bool incp[MAXN];
 76 std::pair<LD, int> hash[MAXN];
 77 
 78 namespace GlobalSEGT
 79 {
 80 
 81 const int SIZE = MAXN << 2;
 82 
 83 int min[SIZE], max[SIZE];
 84 LD sum[SIZE];
 85 int modt[SIZE];
 86 bool modp[SIZE];
 87 bool cleart[SIZE];
 88 int L, R;
 89 int Xmin, Xmax;
 90 LD Xsum;
 91 
 92 #define LC (u << 1)
 93 #define RC (u << 1 | 1)
 94 
 95 inline void tagClear(int u)
 96 {
 97     cleart[u] = true;
 98     sum[u] = 0;
 99 }
100 
101 inline void tagMod(int u, int x)
102 {
103     modp[u] = true;
104     min[u] = max[u] = modt[u] = x;
105 }
106 
107 inline void pushdown(int u)
108 {
109     if (cleart[u]) {
110         tagClear(LC);
111         tagClear(RC);
112         cleart[u] = false;
113     }
114     if (modp[u]) {
115         tagMod(LC, modt[u]);
116         tagMod(RC, modt[u]);
117         modp[u] = false;
118     }
119 }
120 
121 inline void pushup(int u)
122 {
123     min[u] = std::min(min[LC], min[RC]);
124     max[u] = std::max(max[LC], max[RC]);
125     sum[u] = sum[LC] + sum[RC];
126 }
127 
128 void _update(int u, int l = 1, int r = N)
129 {
130     if (l == r) {
131         sum[u] = Xsum;
132         return;
133     }
134     pushdown(u);
135     int mid = (l + r) >> 1;
136     if (L <= mid)
137         _update(LC, l, mid);
138     else
139         _update(RC, mid + 1, r);
140     pushup(u);
141 }
142 
143 void _modify(int u, int l = 1, int r = N)
144 {
145     if (L <= l && r <= R) {
146         tagMod(u, Xmin);
147         return;
148     }
149     pushdown(u);
150     int mid = (l + r) >> 1;
151     if (L <= mid)
152         _modify(LC, l, mid);
153     if (mid < R)
154         _modify(RC, mid + 1, r);
155     pushup(u);
156 }
157 
158 void _clear(int u, int l = 1, int r = N)
159 {
160     if (L <= l && r <= R) {
161         tagClear(u);
162         return;
163     }
164     pushdown(u);
165     int mid = (l + r) >> 1;
166     if (L <= mid)
167         _clear(LC, l, mid);
168     if (mid < R)
169         _clear(RC, mid + 1, r);
170     pushup(u);
171 }
172 
173 void _query(int u, int l = 1, int r = N)
174 {
175     if (L <= l && r <= R) {
176         chkmin(Xmin, min[u]);
177         chkmax(Xmax, max[u]);
178         Xsum += sum[u];
179         return;
180     }
181     pushdown(u);
182     int mid = (l + r) >> 1;
183     if (L <= mid)
184         _query(LC, l, mid);
185     if (mid < R)
186         _query(RC, mid + 1, r);
187 }
188 
189 inline void update(int p, LD sm)
190 {
191     L = p;
192     Xsum = sm;
193     _update(1);
194 }
195 
196 inline void modify(int l, int r, int x)
197 {
198     L = l; R = r;
199     Xmin = x;
200     _modify(1);
201 }
202 
203 inline void clear(int l, int r)
204 {
205     L = l; R = r;
206     _clear(1);
207 }
208 
209 inline void query(int l, int r, int &mn, int &mx, LD &sm)
210 {
211     L = l; R = r;
212     Xmin = +oo; Xmax = -oo; Xsum = 0;
213     _query(1);
214     mn = Xmin; mx = Xmax; sm = Xsum;
215 }
216 
217 }
218 
219 namespace SEGT
220 {
221 
222 const int SIZE = 1e7 + 5;
223 
224 int size, lc[SIZE], rc[SIZE];
225 int cnt[SIZE];
226 LD sum[SIZE];
227 
228 inline void pushup(int u)
229 {
230     cnt[u] = cnt[lc[u]] + cnt[rc[u]];
231     sum[u] = sum[lc[u]] + sum[rc[u]];
232 }
233 
234 void insert(int &u, int p, int l = 1, int r = N)
235 {
236     if (u == 0)
237         u = ++size;
238     if (l == r) {
239         ++cnt[u];
240         sum[u] += hash[l].x;
241         return;
242     }
243     int mid = (l + r) >> 1;
244     if (p <= mid)
245         insert(lc[u], p, l, mid);
246     else
247         insert(rc[u], p, mid + 1, r);
248     pushup(u);
249 }
250 
251 LD query(int u, int lim, int l = 1, int r = N)
252 {
253     if (u == 0 || lim <= 0)
254         return 0;
255     if (cnt[u] <= lim)
256         return sum[u];
257     int mid = (l + r) >> 1;
258     return query(lc[u], lim, l, mid) + query(rc[u], lim - cnt[lc[u]], mid + 1, r);
259 }
260 
261 void merge(int &u, int v, int l = 1, int r = N)
262 {
263     if (v == 0)
264         return;
265     if (u == 0) {
266         u = v;
267         return;
268     }
269     int mid = (l + r) >> 1;
270     merge(lc[u], lc[v], l, mid);
271     merge(rc[u], rc[v], mid + 1, r);
272     pushup(u);
273 }
274 
275 void split(int &u, int &v, int kth, int l = 1, int r = N)
276 {
277     if (v == 0)
278         v = ++size;
279     lc[v] = rc[v] = 0;
280     int mid = (l + r) >> 1;
281     if (cnt[lc[u]] >= kth) {
282         rc[v] = rc[u];
283         rc[u] = 0;
284         if (cnt[lc[u]] > kth)
285             split(lc[u], lc[v], kth, l, mid);
286     } else
287         split(rc[u], rc[v], kth - cnt[lc[u]], mid + 1, r);
288     pushup(u);
289     pushup(v);
290 }
291 
292 }
293 
294 void input()
295 {
296     read(N); read(M);
297     for (int i = 1; i <= N; ++i) {
298         read(A0[i]);
299     }
300 }
301 
302 void solve()
303 {
304     LD bound[15];
305 
306     for (int i = 1; i < 10; ++i) {
307         bound[i] = log10((LD)i);
308     }
309 
310     for (int i = 1; i <= N; ++i) {
311         A[i] = log10((LD)A0[i]);
312         hash[i] = MP(A[i], i);
313     }
314     std::sort(hash + 1, hash + N + 1);
315     for (int i = 1; i <= N; ++i) {
316         id[hash[i].y] = i;
317     }
318 
319     static int root[MAXN];
320 
321     for (int i = 1; i <= N; ++i) {
322         root[i] = ++SEGT::size;
323         SEGT::insert(root[i], id[i]);
324         begin[i] = end[i] = i;
325         GlobalSEGT::modify(i, i, i);
326         GlobalSEGT::update(i, A[i]);
327         incp[i] = true;
328     }
329 
330     while (M--) {
331         int type;
332         int l, r;
333         read(type); read(l); read(r);
334 
335         if (type == 1) {
336             int flag;
337             read(flag);
338 
339             int lp, rp;
340             LD sum;
341             GlobalSEGT::query(l, r, lp, rp, sum);
342             if (begin[lp] < l) {
343                 int s = begin[lp];
344                 if (incp[s])
345                     SEGT::split(root[s], root[l], l - s);
346                 else {
347                     SEGT::split(root[s], root[l], lp + 1 - l);
348                     std::swap(root[s], root[l]);
349                 }
350                 begin[lp] = l;
351                 incp[l] = incp[s];
352                 begin[l - 1] = s;
353                 end[s] = l - 1;
354                 GlobalSEGT::modify(s, l - 1, l - 1);
355                 GlobalSEGT::clear(s, l - 1);
356                 GlobalSEGT::update(s, SEGT::sum[root[s]]);
357             }
358             if (rp > r) {
359                 int t = begin[rp];
360                 if (incp[t])
361                     SEGT::split(root[t], root[r + 1], r + 1 - t);
362                 else {
363                     SEGT::split(root[t], root[r + 1], rp - r);
364                     std::swap(root[t], root[r + 1]);
365                 }
366                 begin[rp] = r + 1;
367                 end[r + 1] = rp;
368                 incp[r + 1] = incp[t];
369                 GlobalSEGT::modify(r + 1, rp, rp);
370                 GlobalSEGT::clear(r + 1, rp);
371                 GlobalSEGT::update(r + 1, SEGT::sum[root[r + 1]]);
372             }
373             for (int j = lp + 1; j <= r; j = end[j] + 1) {
374                 SEGT::merge(root[l], root[j]);
375             }
376 
377             begin[r] = l;
378             end[l] = r;
379             incp[l] = flag;
380             GlobalSEGT::modify(l, r, r);
381             GlobalSEGT::clear(l, r);
382             GlobalSEGT::update(l, SEGT::sum[root[l]]);
383         } else {
384             int lp, rp;
385             LD x;
386             GlobalSEGT::query(l, r, lp, rp, x);
387             if (begin[lp] < l) {
388                 int s = begin[lp];
389                 x += incp[s] ? SEGT::sum[root[s]] - SEGT::query(root[s], l - s) : SEGT::query(root[s], lp + 1 - l);
390             }
391             if (rp > r) {
392                 int t = begin[rp];
393                 x -= incp[t] ? SEGT::sum[root[t]] - SEGT::query(root[t], r + 1 - t) : SEGT::query(root[t], rp - r);
394             }
395 
396             x -= floor(x);
397             int ans = std::upper_bound(bound + 1, bound + 10, x) - bound - 1;
398             write(ans); putchar('\n');
399         }
400     }
401 }
402 
403 int main()
404 {
405 //    freopen("zkb.in", "r", stdin);
406   //  freopen("zkb.out", "w", stdout);
407 
408     input();
409     solve();
410 
411     return 0;
412 }
View Code

 

 posted on 2020-02-28 19:11  GreenDuck  阅读(173)  评论(0编辑  收藏  举报