chessboard

题意:n*n的矩阵,m次赋值一个子矩阵为c,最后输出答案。

n<=1e3 m<=1e5

解:倒序处理。

拆行处理。

每行内并查集维护未被赋值的地方。

这样每个地方最多被赋值一次,每次修改要访问n行,时间复杂度是O(n(n + m))

  1 #include <cstdio>
  2 
  3 inline void read(int &x) {
  4     char c = getchar();
  5     x = 0;
  6     while(c < '0' || c > '9') {
  7         c = getchar();
  8     }
  9     while(c >= '0' && c <= '9') {
 10         x = (x << 3) + (x << 1) + c - 48;
 11         c = getchar();
 12     }
 13     return;
 14 }
 15 
 16 const int N = 1010, M = 100010;
 17 
 18 struct Node {
 19     int opt, c, x, y, xx, yy;
 20 }a[M]; 
 21 
 22 int n, k, m, fa[M], sv[M], num, path[M], top;
 23 char s[10];
 24 
 25 struct ROW {
 26     int a[N], fa[N];
 27     ROW() {
 28         for(int i = 1; i < N; i++) {
 29             fa[i] = i;
 30             a[i] = 1;
 31         }
 32     }
 33     int find(int x) {
 34         if(x == fa[x]) {
 35             return x;
 36         }
 37         return fa[x] = find(fa[x]);
 38     }
 39     inline void change(int v, int l, int r) {
 40         int p = find(r);
 41         while(p >= l) {
 42             a[p] = v;
 43             fa[p] = find(p - 1);
 44             p = fa[p];
 45         }
 46         return;
 47     }
 48 }row1[N], row2[N];
 49 
 50 int main() {
 51     
 52     read(n);
 53     read(k);
 54     read(m);
 55     
 56     for(int i = 1; i <= m; i++) {
 57         scanf("%s", s);
 58         if(s[0] == 'P') { // print
 59             fa[i] = i - 1;
 60             a[i].opt = 1;
 61             read(a[i].c);
 62             read(a[i].x);
 63             read(a[i].y);
 64             read(a[i].xx);
 65             read(a[i].yy);
 66         }
 67         else if(s[0] == 'S') { // save
 68             fa[i] = i - 1;
 69             sv[++num] = i;
 70         }
 71         else { // load
 72             int x;
 73             //scanf("%d", &x);
 74             read(x);
 75             fa[i] = sv[x];
 76         }
 77     }
 78     
 79     int x = m;
 80     while(x) {
 81         path[++top] = x;
 82         x = fa[x];
 83     }
 84     
 85     for(int e = 1; e <= top; e++) {
 86         int i = path[e];
 87         if(!a[i].opt) {
 88             continue;
 89         }
 90         
 91         for(int j = a[i].x + 1; j <= a[i].xx + 1; j++) {
 92             //printf("    j = %d  c = %d \n", j, a[i].c);
 93             if((a[i].x - 1 + a[i].y) & 1) {
 94                 row1[j].change(a[i].c, a[i].y + 1, a[i].yy + 1);
 95             }
 96             else {
 97                 row2[j].change(a[i].c, a[i].y + 1, a[i].yy + 1);
 98             }
 99         }
100     }
101 
102     for(int i = 1; i <= n; i++) {
103         for(int j = 1; j <= n; j++) {
104             if((i + j) & 1) {
105                 printf("%d ", row2[i].a[j]);
106             }
107             else {
108                 printf("%d ", row1[i].a[j]);
109             }
110         }
111         puts("");
112     }
113     return 0;
114 }
AC代码

说一下原来的题意:

有个矩阵,每次间隔染色一个子矩阵(类似国际象棋那样,左上角要染),还要支持存档/读档。最后一次输出。

  1 #include <cstdio>
  2 #include <algorithm>
  3 
  4 inline void read(int &x) {
  5     char c = getchar();
  6     x = 0;
  7     while(c < '0' || c > '9') {
  8         c = getchar();
  9     }
 10     while(c >= '0' && c <= '9') {
 11         x = (x << 3) + (x << 1) + c - 48;
 12         c = getchar();
 13     }
 14     return;
 15 }
 16 
 17 const int N = 1010, M = 100010;
 18 
 19 struct Node {
 20     int opt, c, x, y, xx, yy;
 21 }a[M]; 
 22 
 23 int n, k, m, fa[M], sv[M], num, path[M], top;
 24 char s[10];
 25 int sa[N * N * 4], sb[N * N * 4], sc[N * N * 4], sd[N * N * 4];
 26 int tag1[N * N * 4], tag2[N * N * 4], G[N][N];
 27 
 28 void build(int x, int y, int xx, int yy, int o) {
 29     if(x == xx && y == yy) {
 30         tag1[o] = 1;
 31         return;
 32     }
 33     int mx = (x + xx) >> 1;
 34     int my = (y + yy) >> 1;
 35     
 36     sa[o] = ++num;
 37     build(x, y, mx, my, num);
 38     
 39     if(yy > y) {
 40         sb[o] = ++num;
 41         build(x, my + 1, mx, yy, num);
 42     }
 43     if(xx > x) {
 44         sc[o] = ++num;
 45         build(mx + 1, y, xx, my, num);
 46     }
 47     
 48     if(yy > y && xx > x) {
 49         sd[o] = ++num;
 50         build(mx +1, my + 1, xx, yy, num);
 51     }
 52     return;
 53 }
 54 
 55 inline void pushdown(int x, int y, int xx, int yy, int o) {
 56     int mx = (x + xx) >> 1;
 57     int my = (y + yy) >> 1;
 58     if(tag1[o]) {
 59         int t = tag1[o];
 60         if(sa[o]) {
 61             tag1[sa[o]] = t;
 62         }
 63         if(sb[o]) {
 64             if((my - y + 1) & 1) {
 65                 tag2[sb[o]] = t;
 66             }
 67             else {
 68                 tag1[sb[o]] = t;
 69             }
 70         }
 71         if(sc[o]) {
 72             if((mx - x + 1) & 1) {
 73                 tag2[sc[o]] = t;
 74             }
 75             else {
 76                 tag1[sc[o]] = t;
 77             }
 78         }
 79         if(sd[o]) {
 80             if((mx - x + my - y + 1) & 1) {
 81                 tag1[sd[o]] = t;
 82             }
 83             else {
 84                 tag2[sd[o]] = t;
 85             }
 86         }
 87         tag1[o] = 0;
 88     }
 89     if(tag2[o]) {
 90         int t = tag2[o];
 91         if(sa[o]) {
 92             tag2[sa[o]] = t;
 93         }
 94         if(sb[o]) {
 95             if((my - y + 1) & 1) {
 96                 tag1[sb[o]] = t;
 97             }
 98             else {
 99                 tag2[sb[o]] = t;
100             }
101         }
102         if(sc[o]) {
103             if((mx - x + 1) & 1) {
104                 tag1[sc[o]] = t;
105             }
106             else {
107                 tag2[sc[o]] = t;
108             }
109         }
110         if(sd[o]) {
111             if((mx - x + my - y + 1) & 1) {
112                 tag2[sd[o]] = t;
113             }
114             else {
115                 tag1[sd[o]] = t;
116             }
117         }
118         tag2[o] = 0;
119     }
120     return;
121 }
122 
123 int X, XX, Y, YY;
124 inline void change(int v, int f, int x, int y, int xx, int yy, int o) {
125     int mx = (x + xx) >> 1;
126     int my = (y + yy) >> 1;
127     if(X <= x && xx <= XX) {
128         if(Y <= y && yy <= YY) {
129             if(f) {
130                 tag1[o] = v;
131             }
132             else {
133                 tag2[o] = v;
134             }
135             return;
136         }
137     }
138     pushdown(x, y, xx, yy, o);
139     if(X <= mx && Y <= my) { // sa
140         change(v, f, x, y, mx, my, sa[o]);
141     }
142     if(X <= mx && my < YY) { // sb
143         if((my - y + 1) & 1) {
144             change(v, f ^ 1, x, my + 1, mx, yy, sb[o]);
145         }
146         else {
147             change(v, f, x, my + 1, mx, yy, sb[o]);
148         }
149     }
150     if(mx < XX && Y <= my) { // sc
151         if((mx - x + 1) & 1) {
152             change(v, f ^ 1, mx + 1, y, xx, my, sc[o]);
153         }
154         else {
155             change(v, f, mx + 1, y, xx, my, sc[o]);
156         }
157     }
158     if(mx < XX && my < YY) { // sd
159         if((mx - x + my - y + 1) & 1) {
160             change(v, f, mx + 1, my + 1, xx, yy, sd[o]);
161         }
162         else {
163             change(v, f ^ 1, mx + 1, my + 1, xx, yy, sd[o]);
164         }
165     }
166     return;
167 }
168 
169 void ed(int x, int y, int xx, int yy, int o) {
170     if(x == xx && y == yy) {
171         G[x][y] = tag1[o];
172         return;
173     }
174     int mx = (x + xx) >> 1;
175     int my = (y + yy) >> 1;
176     pushdown(x, y, xx, yy, o);
177     ed(x, y, mx, my, sa[o]);
178     if(yy > y) {
179         ed(x, my + 1, mx, yy, sb[o]);
180     }
181     if(xx > x) {
182         ed(mx + 1, y, xx, my, sc[o]);
183     }
184     if(xx > x && yy > y) {
185         ed(mx + 1, my + 1, xx, yy, sd[o]);
186     }
187     return;
188 }
189 
190 int main() {
191     
192     read(n);
193     read(k);
194     read(m);
195     
196     for(int i = 1; i <= m; i++) {
197         scanf("%s", s);
198         if(s[0] == 'P') { // print
199             fa[i] = i - 1;
200             a[i].opt = 1;
201             read(a[i].c);
202             read(a[i].x);
203             read(a[i].y);
204             read(a[i].xx);
205             read(a[i].yy);
206         }
207         else if(s[0] == 'S') { // save
208             fa[i] = i - 1;
209             sv[++num] = i;
210         }
211         else { // load
212             int x;
213             read(x);
214             fa[i] = sv[x];
215         }
216     }
217     
218     int x = m;
219     while(x) {
220         path[++top] = x;
221         x = fa[x];
222     }
223     std::reverse(path + 1, path + top + 1);
224     num = 1;
225     build(1, 1, n, n, 1);
226     for(int e = 1; e <= top; e++) {
227         int i = path[e];
228         if(!a[i].opt) {
229             continue;
230         }
231         a[i].x++;
232         a[i].xx++;
233         a[i].y++;
234         a[i].yy++;
235         X = a[i].x;
236         Y = a[i].y;
237         XX = a[i].xx;
238         YY = a[i].yy;
239         if((a[i].x - 1 + a[i].y) & 1) {
240             change(a[i].c, 1, 1, 1, n, n, 1);
241         }
242         else {
243             change(a[i].c, 0, 1, 1, n, n, 1);
244         }
245     }
246     
247     
248     ed(1, 1, n, n, 1);
249     for(int i = 1; i <= n; i++) {
250         for(int j = 1; j <= n; j++) {
251             printf("%d ", G[i][j]);
252         }
253         puts("");
254     }
255     return 0;
256 }
四分树

这是考场上写的,四分树每次修改貌似是O(n)的,但是卡成6s......只有75分。

话说我第一次写四分树居然是在考场上,而且一个字符都没调就一次写对了......

时间复杂度到底是多少呀......nm的话应该能过呀?莫非是我常数大?

posted @ 2018-10-30 21:10  huyufeifei  阅读(319)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜