给定
一个显而易见的思路,用
(最后拿到了 ty > M ? M : ty
最开始写成
xxxxxxxxxx
1461
2
3
4
5
6
7
8
9
10
11
12using namespace std;
13
14mt19937 rnd(random_device{}());
15int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
16bool rnddd(int x){return rndd(1, 100) <= x;}
17
18typedef unsigned int uint;
19typedef unsigned long long unll;
20typedef long long ll;
21typedef long double ld;
22
23template < typename T = int >
24inline T read(void);
25
26int N, M;
27vector < vector < bool > > mp;
28vector < vector < int > > sum;
29vector < vector < bool > > mark;
30vector < vector < int > > csum;
31
32bool Check(int siz){
33 for(int i = 1; i <= N; ++i)
34 for(int j = 1; j <= M; ++j)
35 mark[i][j] = false, csum[i][j] = 0;
36 for(int i = siz + 1; i <= N - siz; ++i){
37 for(int j = siz + 1; j <= M - siz; ++j){
38 int sx = i - siz, sy = j - siz, tx = i + siz, ty = j + siz;
39 int rsum = sum[tx][ty] - sum[sx - 1][ty] - sum[tx][sy - 1] + sum[sx - 1][sy - 1];
40 int esum = ((siz << 1) | 1) * ((siz << 1) | 1);
41 if(esum == rsum)mark[i][j] = true;
42 }
43 }
44 for(int i = 1; i <= N; ++i)
45 for(int j = 1; j <= M; ++j)
46 csum[i][j] = csum[i - 1][j] + csum[i][j - 1] - csum[i - 1][j - 1] + mark[i][j];
47 for(int i = 1; i <= N; ++i)
48 for(int j = 1; j <= M; ++j){
49 int sx = i - siz, sy = j - siz, tx = i + siz, ty = j + siz;
50 if(mp[i][j] && !(csum[tx > N ? N : tx][ty > M ? M : ty] - csum[tx > N ? N : tx][sy - 1 < 0 ? 0 : sy - 1] - csum[sx - 1 < 0 ? 0 : sx - 1][ty > M ? M : ty] + csum[sx - 1 <= 0 ? 0 : sx - 1][sy - 1 < 0 ? 0 : sy - 1]))
51 return false;
52 }
53 return true;
54}
55
56int main(){
57 freopen("yawn.in", "r", stdin);
58 freopen("yawn.out", "w", stdout);
59 N = read(), M = read();
60 for(int i = 0; i <= N; ++i){
61 mark.emplace_back(vector < bool >());
62 csum.emplace_back(vector < int >());
63 for(int j = 0; j <= M; ++j)
64 // mark[i] += false, csum[i] += 0;
65 mark[i].emplace_back(false), csum[i].emplace_back(0);
66 }
67 // mp += vector < bool >();
68 mp.emplace_back(vector < bool >());
69 // vis += vector < bool >();
70 for(int i = 0; i <= M; ++i)mp[0].emplace_back(false);//, vis[0] += false;
71 for(int i = 1; i <= N; ++i){
72 mp.emplace_back(vector < bool >());// += vector < bool >();
73 // vis += vector < bool >();
74 // mp[i] += false;//, vis[i] += false;
75 mp[i].emplace_back(false);
76 for(int j = 1; j <= M; ++j){
77 char c = getchar(); while(c != '.' && c != 'X')c = getchar();
78 // mp[i] += c == '.' ? false : true;
79 mp[i].emplace_back(c == '.' ? false : true);
80 // vis[i] += c == '.' ? false : true;
81 }
82 }
83 // sum += vector < int >();
84 sum.emplace_back(vector < int >());
85 for(int i = 0; i <= M; ++i)sum[0].emplace_back(0); //sum[0] += 0;
86 for(int i = 1; i <= N; ++i){
87 // sum += vector < int >();
88 sum.emplace_back(vector < int >());
89 // sum[i] += 0;
90 sum[i].emplace_back(0);
91 for(int j = 1; j <= M; ++j)
92 // sum[i] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + mp[i][j];
93 sum[i].emplace_back(sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + mp[i][j]);
94 }
95
96 printf("Checking 50 %d\n\n\n\n\n", Check(50) ? 1 : 0);
97
98
99 int l = 1, r = min((N - 1) >> 1, (M - 1) >> 1), ans = -1;
100 while(l <= r){
101 int mid = (l + r) >> 1;
102 if(Check(mid))ans = mid, l = mid + 1;
103 else r = mid - 1;
104 }
105 if(!~ans){
106 printf("0\n");
107 for(int i = 1; i <= N; ++i)
108 for(int j = 1; j <= M; ++j)
109 printf("%c%s", mp[i][j] ? 'X' : '.', j == M ? "\n" : "");
110 exit(0);
111 }
112 int siz = ans;
113 for(int i = 1; i <= N; ++i)
114 for(int j = 1; j <= M; ++j)
115 mark[i][j] = false;
116 for(int i = siz + 1; i <= N - siz; ++i){
117 for(int j = siz + 1; j <= M - siz; ++j){
118 int sx = i - siz, sy = j - siz, tx = i + siz, ty = j + siz;
119 int rsum = sum[tx][ty] - sum[sx - 1][ty] - sum[tx][sy - 1] + sum[sx - 1][sy - 1];
120 int esum = ((siz << 1) | 1) * ((siz << 1) | 1);
121 if(esum == rsum)mark[i][j] = true;
122 }
123 }
124 printf("%d\n", ans);
125 for(int i = 1; i <= N; ++i)
126 for(int j = 1; j <= M; ++j)
127 printf("%c%s", mark[i][j] ? 'X' : '.', j == M ? "\n" : "");
128 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
129 return 0;
130}
131
132template < typename T >
133inline T read(void){
134 T ret(0);
135 int flag(1);
136 char c = getchar();
137 while(c != '-' && !isdigit(c))c = getchar();
138 if(c == '-')flag = -1, c = getchar();
139 while(isdigit(c)){
140 ret *= 10;
141 ret += int(c - '0');
142 c = getchar();
143 }
144 ret *= flag;
145 return ret;
146}
给定序列,每次从序列中取数直至取空,每次取
赛时思路是考虑记录
xxxxxxxxxx
1031/*
22
35
47 10 4 9 4
53
62 1 7
7
83
97
1022 34 48 12 48 37 27
1110
1219 37 37 51 40 87 25 28 81 26
139
1451 60 21 52 25 46 40 37 3
15*/
16
17
18
19
20
21
22
23
24
25
26
27using namespace std;
28
29mt19937 rnd(random_device{}());
30int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
31bool rnddd(int x){return rndd(1, 100) <= x;}
32
33typedef unsigned int uint;
34typedef unsigned long long unll;
35typedef long long ll;
36typedef long double ld;
37
38template < typename T = int >
39inline T read(void);
40
41int N;
42int A[1100000];
43int val[1100000];
44int pri[1100000];
45int pre[1100000], nxt[1100000];
46bitset < 1100000 > vis;
47ll ans(0);
48
49priority_queue < pair < int, int >, vector < pair < int, int > >, less < pair < int, int > > > cur;
50
51int main(){
52 freopen("sum.in", "r", stdin);
53 freopen("sum.out", "w", stdout);
54 int T = read();
55 while(T--){
56 for(int i = 0; i <= N + 1; ++i)vis[i] = false;
57 N = read();
58 A[0] = A[N + 1] = 0; pre[0] = 0, nxt[N + 1] = N + 1, pre[N + 1] = N, nxt[0] = 1;
59 val[0] = val[N + 1] = pri[0] = pri[N + 1] = 0, ans = 0;
60 for(int i = 1; i <= N; ++i)A[i] = read();
61 for(int i = 1; i <= N; ++i)pre[i] = i - 1, nxt[i] = i + 1;
62 for(int i = 1; i <= N; ++i)val[i] = min(A[pre[i]], A[nxt[i]]);
63 for(int i = 1; i <= N; ++i)pri[i] = val[i] - (val[pre[i]] - min(A[pre[pre[i]]], A[nxt[i]])) - (val[nxt[i]] - min(A[nxt[nxt[i]]], A[pre[i]]));
64 for(int i = 1; i <= N; ++i)cur.push({pri[i], i});
65 while(!cur.empty()){
66 auto tp = cur.top(); cur.pop();
67 int idx = tp.second;
68 if(tp.first != pri[idx] || vis[idx])continue;
69 ans += val[idx], vis[idx] = true;
70 val[pre[idx]] = min(A[pre[pre[idx]]], A[nxt[idx]]);
71 val[nxt[idx]] = min(A[nxt[nxt[idx]]], A[pre[idx]]);
72 pri[pre[idx]] = val[pre[idx]] - (val[pre[pre[idx]]] - min(A[pre[pre[pre[idx]]]], A[nxt[idx]])) - (val[nxt[idx]] - min(A[nxt[nxt[idx]]], A[pre[pre[idx]]]));
73 pri[nxt[idx]] = val[nxt[idx]] - (val[pre[idx]] - min(A[pre[pre[idx]]], A[nxt[nxt[idx]]])) - (val[nxt[nxt[idx]]] - min(A[nxt[nxt[nxt[idx]]]], A[pre[idx]]));
74 cur.push({pri[pre[idx]], pre[idx]}), cur.push({pri[nxt[idx]], nxt[idx]});
75 nxt[pre[idx]] = nxt[idx], pre[nxt[idx]] = pre[idx];
76 int i = pre[pre[idx]];
77 pri[i] = val[i] - (val[pre[i]] - min(A[pre[pre[i]]], A[nxt[i]])) - (val[nxt[i]] - min(A[nxt[nxt[i]]], A[pre[i]]));
78 cur.push({pri[i], i});
79 i = nxt[nxt[idx]];
80 pri[i] = val[i] - (val[pre[i]] - min(A[pre[pre[i]]], A[nxt[i]])) - (val[nxt[i]] - min(A[nxt[nxt[i]]], A[pre[i]]));
81 cur.push({pri[i], i});
82 }printf("%lld\n", ans);
83 }
84
85 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
86 return 0;
87}
88
89template < typename T >
90inline T read(void){
91 T ret(0);
92 // int flag(1);
93 char c = getchar();
94 while(!isdigit(c))c = getchar();
95 // if(c == '-')flag = -1, c = getchar();
96 while(isdigit(c)){
97 ret *= 10;
98 ret += int(c - '0');
99 c = getchar();
100 }
101 // ret *= flag;
102 return ret;
103}
给定序列
给定
赛时写了个暴力,就不挂 Code 了。
奇怪题,没写。
考虑三个数
首先说一下 @sssmzy 的高妙思路(确实巧妙,必须 %%%%%%%
考虑下取整的意义就是正常的除法之后再取整,于是直接考虑我们不考虑下取整,认为其为标准除法,然后则可以在线段树上合并,最后再取整即可。有一个问题就是这个东西并不是适用于所有,本题适用应该是因为对于 long double
,会 long double
真的很慢。(@sssmzy 就是因为 long double
而
update-2023_02_16 初稿