00001
00002
00004
00005 #ifndef PAR_H
00006 #define PAR_H
00007
00008 #include <iomanip>
00009 #include <stdlib.h>
00010 #include <cmath>
00011 #include <stack>
00012
00013 using namespace std;
00014
00016 template <class T> static T par_add(T x, T y) { return x + y; }
00017 template <class T> static T par_sub(T x, T y) { return x - y; }
00018 template <class T> static T par_mul(T x, T y) { return x * y; }
00019 template <class T> static T par_div(T x, T y) { return x / y; }
00020 template <class T> static T par_mod(T x, T y) { return x % y; }
00021 template <class T> static T par_or(T x, T y) { return x | y; }
00022 template <class T> static T par_and(T x, T y) { return x & y; }
00023 template <class T> static T par_max(T x, T y) { return x>=y ? x : y; }
00024 template <class T> static T par_min(T x, T y) { return x<=y ? x : y; }
00025 template <class T> static T par_neg(T x) { return -x; }
00026 template <class T> static T par_nop(T x) { return x; }
00027 template <class T> static T par_not(T x) { return !x; }
00028
00029
00030
00031 template <class T> static T par_pow(T x, T y) { return pow(x,y); }
00032
00034 template <class T> static bool par_eq(T x, T y){ return x==y; }
00035 template <class T> static bool par_ne(T x, T y){ return x!=y; }
00036 template <class T> static bool par_lt(T x, T y){ return x<y; }
00037 template <class T> static bool par_gt(T x, T y){ return x>y; }
00038 template <class T> static bool par_le(T x, T y){ return x<=y; }
00039 template <class T> static bool par_ge(T x, T y){ return x>=y; }
00040
00042 bool *flag=NULL;
00043 int flag_N=0;
00044
00046 bool *flagtemp=NULL;
00047 bool restrict=false;
00048 bool ifelseflag=true;
00049
00051 stack<bool *> rs;
00052 stack<bool> ifelses;
00053
00055 #define ifp(x) \
00056 (x); \
00057 flagtemp = new bool[flag_N]; \
00058 memcpy(flagtemp, flag, flag_N); \
00059 rs.push(flagtemp); \
00060 ifelses.push(true); \
00061 restrict = true; \
00062 ifelseflag = true;
00063
00064
00066 #define elsep() \
00067 flagtemp = rs.top(); \
00068 ifelseflag = false; \
00069 ifelses.pop(); \
00070 ifelses.push(false);
00071
00073 #define endifp \
00074 flagtemp = rs.top(); \
00075 delete [] flagtemp; \
00076 rs.pop(); \
00077 ifelses.pop(); \
00078 if (!ifelses.empty()) ifelseflag = ifelses.top(); \
00079 else ifelseflag = true; \
00080 if (!rs.empty()) flagtemp = rs.top(); \
00081 else { flagtemp=NULL; restrict = false; }
00082
00083
00084
00086
00087 template <class T>
00088 class par
00089 {
00091 private:
00092 T *data;
00093 int N;
00094
00096 public:
00097
00098 par(const int n=1)
00099 {
00100 N = n;
00101 data = new T[n];
00102 }
00103
00104 ~par()
00105 { delete [] data; }
00106
00107 par(const par<T> &x)
00108 {
00109 for (int i=0; i<x.N; i++)
00110 data[i] = x.data[i];
00111 N = x.N;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00123
00125 friend void par_bool_par(par<T> &x, bool f(T,T), par<T> &y)
00126 {
00127 delete [] flag;
00128 flag = new bool[x.N];
00129 flag_N = x.N;
00130 for (int i=0; i<x.N; i++)
00131 {
00132 flag[i] = f(x.data[i],y.data[i]);
00133 }
00134 }
00135
00136 friend void par_bool_sing(par<T> &x, bool f(T,T), const T &t)
00137 {
00138 par<T> y(x.N);
00139 y=t;
00140 par_bool_par(x,f,y);
00141 }
00142
00144 friend void par_self(par<T> &x, T f(T))
00145 {
00146 for (int i=0; i<x.N; i++)
00147 x.data[i] = f(x.data[i]);
00148 }
00149
00150 friend void par_to_par(par<T> &y, T f(T), par<T> &x)
00151 {
00152 for (int i=0; i<y.N; i++)
00153 y.data[i] = f(x.data[i]);
00154 }
00155
00156 void par2_to_par(T f(T,T) , par<T> &x, par<T> &y)
00157 {
00158 for (int i=0; i<N; i++)
00159 data[i] = f(x.data[i],y.data[i]);
00160 }
00161
00164 friend void sing_to_par(par<T> &y, T f(T), const T &t)
00165 {
00166 for (int i=0; i<y.N; i++)
00167 y.data[i] = f(t);
00168 }
00169
00170 friend void par_and_sing_to_par(par<T> &z, T f(T,T), par<T> &x, const T &t)
00171 {
00172 par<T> y(x.N); y=t;
00173 z.par2_to_par(f,x,y);
00174 }
00175
00176 friend void par_and_sing_to_par_rev(par<T> &z, T f(T,T), par<T> &x, const T &t)
00177 {
00178 par<T> y(x.N); y=t;
00179 z.par2_to_par(f,y,x);
00180 }
00181
00182
00183
00185
00187 par<T> &operator - ()
00188 { static par<T> z(N); z.reassign(N); par_to_par(z ,par_neg ,*this ); return z;}
00189
00190 par<T> &operator ! ()
00191 { static par<T> z(N); z.reassign(N); par_to_par(z ,par_not ,*this ); return z;}
00192
00193 par<T> &operator + ()
00194 { return *this; }
00195
00196
00198 par<T> &operator + (par<T> &y)
00199 {static par<T> z(N); z.reassign(N); z.par2_to_par( par_add, *this, y); return z;}
00200
00201 par<T> &operator - (par<T> &y)
00202 {static par<T> z(N); z.reassign(N); z.par2_to_par( par_sub, *this, y); return z;}
00203
00204 par<T> &operator * (par<T> &y)
00205 {static par<T> z(N); z.reassign(N); z.par2_to_par( par_mul, *this, y); return z;}
00206
00207 par<T> &operator / (par<T> &y)
00208 {static par<T> z(N); z.reassign(N); z.par2_to_par( par_div, *this, y); return z;}
00209
00210 par<T> &operator % (par<T> &y)
00211 {static par<T> z(N); z.reassign(N); z.par2_to_par( par_mod, *this, y); return z;}
00212
00213 par<T> &operator | (par<T> &y)
00214 {static par<T> z(N); z.reassign(N); z.par2_to_par( par_or, *this, y); return z;}
00215
00216 par<T> &operator & (par<T> &y)
00217 {static par<T> z(N); z.reassign(N); z.par2_to_par( par_and, *this, y); return z;}
00218
00220 par<T> &operator += (par<T> &y)
00221 {this->par2_to_par( par_add, *this, y); return *this;}
00222
00223 par<T> &operator -= (par<T> &y)
00224 {this->par2_to_par( par_sub, *this, y); return *this;}
00225
00226 par<T> &operator *= (par<T> &y)
00227 {this->par2_to_par( par_mul, *this, y); return *this;}
00228
00229 par<T> &operator /= (par<T> &y)
00230 {this->par2_to_par( par_div, *this, y); return *this;}
00231
00232 par<T> &operator %= (par<T> &y)
00233 {this->par2_to_par( par_mod, *this, y); return *this;}
00234
00235 par<T> &operator |= (par<T> &y)
00236 {this->par2_to_par( par_or, *this, y); return *this;}
00237
00238 par<T> &operator &= (par<T> &y)
00239 {this->par2_to_par( par_and, *this, y); return *this;}
00240
00242 friend T reduce(T init, T f(T,T), const par<T> &x)
00243 { for (int i=0; i<x.N; i++) init = f(init , x.data[i]); return init; }
00244
00245 friend T operator += (T &x, par<T> &y)
00246 {return x=reduce( 0, par_add, y);}
00247
00248 friend T operator -= (T &x, par<T> &y)
00249 {return x=reduce( 0, par_sub, y);}
00250
00251 friend T operator *= (T &x, par<T> &y)
00252 {return x=reduce( 1, par_mul, y);}
00253
00254 friend T operator /= (T &x, par<T> &y)
00255 {return x=reduce( 1, par_div, y);}
00256
00257 friend T operator %= (T &x, par<T> &y)
00258 {return x=reduce( 1, par_mod, y);}
00259
00260 friend T operator |= (T &x, par<T> &y)
00261 {return x=reduce( false, par_or, y);}
00262
00263 friend T operator &= (T &x, par<T> &y)
00264 {return x=reduce( true, par_and, y);}
00265
00266 T max_value(par<T> &y)
00267 {return reduce( y.data[0], par_max, y);}
00268
00269 T min_value(par<T> &y)
00270 {return reduce( y.data[0], par_min, y);}
00271
00272
00273
00275
00276 friend par<bool> &flag_setup_x_op_y(par<T> &x)
00277 {static par<bool> r(x.N); r.reassign(x.N); r=flag; return r;}
00278
00279 friend par<bool> &operator == (par<T> &x, par<T> &y)
00280 { par_bool_par(x, par_eq, y); return flag_setup_x_op_y(x);}
00281
00282 friend par<bool> &operator != (par<T> &x, par<T> &y)
00283 { par_bool_par(x, par_ne, y); return flag_setup_x_op_y(x);}
00284
00285 friend par<bool> &operator < (par<T> &x, par<T> &y)
00286 { par_bool_par(x, par_lt, y); return flag_setup_x_op_y(x);}
00287
00288 friend par<bool> &operator > (par<T> &x, par<T> &y)
00289 { par_bool_par(x, par_gt, y); return flag_setup_x_op_y(x);}
00290
00291 friend par<bool> &operator <= (par<T> &x, par<T> &y)
00292 { par_bool_par(x, par_le, y); return flag_setup_x_op_y(x);}
00293
00294 friend par<bool> &operator >= (par<T> &x, par<T> &y)
00295 { par_bool_par(x, par_ge, y); return flag_setup_x_op_y(x);}
00296
00297 friend par<bool> &operator && (par<T> &x, par<T> &y)
00298 { par_bool_par(x, par_and, y); return flag_setup_x_op_y(x);}
00299
00300 friend par<bool> &operator || (par<T> &x, par<T> &y)
00301 { par_bool_par(x, par_or, y); return flag_setup_x_op_y(x);}
00302
00304 friend par<bool> &operator == (par<T> &x, const T &t)
00305 { par_bool_sing(x, par_eq, t); return flag_setup_x_op_y(x);}
00306
00307 friend par<bool> &operator != (par<T> &x, const T &t)
00308 { par_bool_sing(x, par_ne, t); return flag_setup_x_op_y(x);}
00309
00310 friend par<bool> &operator < (par<T> &x, const T &t)
00311 { par_bool_sing(x, par_lt, t); return flag_setup_x_op_y(x);}
00312
00313 friend par<bool> &operator > (par<T> &x, const T &t)
00314 { par_bool_sing(x, par_gt, t); return flag_setup_x_op_y(x);}
00315
00316 friend par<bool> &operator <= (par<T> &x, const T &t)
00317 { par_bool_sing(x, par_le, t); return flag_setup_x_op_y(x);}
00318
00319 friend par<bool> &operator >= (par<T> &x, const T &t)
00320 { par_bool_sing(x, par_ge, t); return flag_setup_x_op_y(x);}
00321
00322 friend par<bool> &operator == (const T &t, par<T> &x)
00323 { par_bool_sing(t, par_eq, x); return flag_setup_x_op_y(x);}
00324
00325 friend par<bool> &operator != (const T &t, par<T> &x)
00326 { par_bool_sing(t, par_ne, x); return flag_setup_x_op_y(x);}
00327
00328 friend par<bool> &operator < (const T &t, par<T> &x)
00329 { par_bool_sing(t, par_lt, x); return flag_setup_x_op_y(x);}
00330
00331 friend par<bool> &operator > (const T &t, par<T> &x)
00332 { par_bool_sing(t, par_gt, x); return flag_setup_x_op_y(x);}
00333
00334 friend par<bool> &operator >= (const T &t, par<T> &x)
00335 { par_bool_sing(t, par_ge, x); return flag_setup_x_op_y(x);}
00336
00337 friend par<bool> &operator <= (const T &t, par<T> &x)
00338 { par_bool_sing(t, par_le, x); return flag_setup_x_op_y(x);}
00339
00340 friend par<bool> &operator && (const T &t, par<T> &x)
00341 { par_bool_sing(t, par_and, x); return flag_setup_x_op_y(x);}
00342
00343 friend par<bool> &operator && (par<T> &x, const T &t)
00344 { par_bool_sing(t, par_and, x); return flag_setup_x_op_y(x);}
00345
00346 friend par<bool> &operator || (const T &t, par<T> &x)
00347 { par_bool_sing(t, par_and, x); return flag_setup_x_op_y(x);}
00348
00349 friend par<bool> &operator || (par<T> &x, const T &t)
00350 { par_bool_sing(t, par_and, x); return flag_setup_x_op_y(x);}
00351
00352
00354 friend par<T> &operator + (par<T> &x, const T &t)
00355 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_add, x, t); return z;}
00356
00357 friend par<T> &operator + (const T &t, par<T> &x)
00358 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_add, x, t); return z;}
00359
00360 friend par<T> &operator - (par<T> &x, const T &t)
00361 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_sub, x, t); return z;}
00362
00363 friend par<T> &operator - (const T &t, par<T> &x)
00364 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_sub, x, t); return z;}
00365
00366 friend par<T> &operator * (par<T> &x, const T &t)
00367 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_mul, x, t); return z;}
00368
00369 friend par<T> &operator * (const T &t, par<T> &x)
00370 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_mul, x, t); return z;}
00371
00372 friend par<T> &operator / (par<T> &x, const T &t)
00373 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_div, x, t); return z;}
00374
00375 friend par<T> &operator / (const T &t, par<T> &x)
00376 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_div, x, t); return z;}
00377
00378 friend par<T> &operator % (par<T> &x, const T &t)
00379 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_mod, x, t); return z;}
00380
00381 friend par<T> &operator % (const T &t, par<T> &x)
00382 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_mod, x, t); return z;}
00383
00384 friend par<T> &operator | (par<T> &x, const T &t)
00385 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_or, x, t); return z;}
00386
00387 friend par<T> &operator | (const T &t, par<T> &x)
00388 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_or, x, t); return z;}
00389
00390 friend par<T> &operator & (par<T> &x, const T &t)
00391 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_and, x, t); return z;}
00392
00393 friend par<T> &operator & (const T &t, par<T> &x)
00394 {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_and, x, t); return z;}
00395
00397 par<T> &operator ++ ()
00398 {
00399 par_and_sing_to_par(*this, par_add, *this, 1);
00400 return *this;
00401 }
00402
00403 par<T> &operator ++ (int a)
00404 {
00405 static par<T> z(N); z.reassign(N);
00406 par_and_sing_to_par(*z, par_add, *this, 1);
00407 return z;
00408 }
00409
00410 par<T> &operator -- ()
00411 {
00412 par_and_sing_to_par(*this, par_sub, *this, 1);
00413 return *this;
00414 }
00415
00416 par<T> &operator -- (int a)
00417 {
00418 static par<T> z(N); z.reassign(N);
00419 par_and_sing_to_par(z, par_sub, *this, 1);
00420 return z;
00421 }
00422
00423
00425
00426 friend std::ostream &operator << ( std::ostream &out, par<T> &x)
00427 {
00428 for (int i=0; i<x.N; i++)
00429 out << std::setw(12) << x.data[i];
00430 return out;
00431 }
00432
00433
00434 friend std::istream &operator >> ( std::istream &in, par<T> &x)
00435 {
00436 for (int i=0; i<x.N; i++)
00437 in >> x.data[i];
00438 return in;
00439 }
00440
00442
00443 T &operator [] ( int i )
00444 { return data[i]; }
00445
00446 const T &operator [] ( int i ) const
00447 { return data[i]; }
00448
00449 par<T> &operator [] ( par<T> &x )
00450 {
00451 static par<T> z(x.N); z.reassign(x.N);
00452 for (int i=0; i<x.N; i++)
00453 z.data[i] = data[ x.data[i]%x.N ];
00454 return z;
00455 }
00456
00457
00458
00460
00462 par<T> &operator = (const par<T> &x)
00463 {
00464 if (flagtemp !=NULL && restrict)
00465 for (int i=0; i<N; i++)
00466 {if (flagtemp[i]) data[i] = x.data[i];}
00467 else
00468 for (int i=0; i<N; i++)
00469 data[i] = x.data[i];
00470 return *this;
00471 }
00472
00473
00476 par<T> &operator = (const T &t)
00477 {
00478 if (flagtemp !=NULL && restrict)
00479 for (int i=0; i<N; i++)
00480 {if (flagtemp[i]) data[i] = t;}
00481 else
00482 for (int i=0; i<N; i++)
00483 data[i]=t;
00484 return *this;
00485 }
00486
00488 par<T> &operator = (const T *t)
00489 {
00490 if (flagtemp !=NULL && restrict)
00491 for (int i=0; i<N; i++)
00492 { if (flag[i]) data[i] = t[i]; }
00493 else
00494 for (int i=0; i<N; i++)
00495 data[i]=t[i];
00496 return *this;
00497 }
00498
00499
00500
00501
00503
00505
00506 friend void addr(par<T> &x)
00507 { for (int i=0; i<x.N; i++) x.data[i] = i; }
00508
00509 void all_on()
00510 {
00511 delete [] flag;
00512 flag = new bool[N];
00513 flag_N = N;
00514 for (int i=0; i<flag_N; i++) flag[i]=true;
00515 }
00516
00517 friend T first(const par<T> &x)
00518 {
00519 if (flag != NULL)
00520 for (int i=0; i<x.N; i++)
00521 if (flag[i]) return x.data[i];
00522 return x.data[0];
00523 }
00524
00525 friend int first_index(const par<T> &x)
00526 {
00527 if (flag != NULL)
00528 for (int i=0; i<x.N; i++)
00529 if (flag[i]) return i;
00530 return -1;
00531 }
00532
00533 friend T nth(const par<T> &x, int n)
00534 {
00535 int c=0;
00536 if (flag != NULL)
00537 for (int i=0; i<x.N; i++)
00538 if (flag[i])
00539 {
00540 c++;
00541 if (c==n) return x.data[i];
00542 }
00543 return x.data[0];
00544 }
00545
00546 friend T nth_index(const par<T> &x, int n)
00547 {
00548 int c=0;
00549 if (flag != NULL)
00550 for (int i=0; i<x.N; i++)
00551 if (flag[i])
00552 {
00553 c++;
00554 if (c==n) return i;
00555 }
00556 return -1;
00557 }
00558
00559 friend bool any(par<T> &x)
00560 {
00561 for (int i=0; i<x.N; i++)
00562 if (x.data[i]) return true;
00563 return false;
00564 }
00565
00566 friend bool all(par<T> &x)
00567 {
00568 for (int i=0; i<x.N; i++)
00569 if (!x.data[i]) return false;
00570 return true;
00571 }
00572
00573 friend int active(par<T> &x)
00574 {
00575 int c=0;
00576 for (int i=0; i<x.N; i++)
00577 if (flag[i]) c++;
00578 return c;
00579 }
00580
00581 friend par<T> &scan(T init, T f(T,T), const par<T> &x)
00582 {
00583 static par<T> z(N); z.reassign(N);
00584 z.data[0] = x.data[0];
00585 for (int i=1; i<x.N; i++)
00586 z.data[i] = f(z.data[i-1], x.data[i]);
00587 return z;
00588 }
00589
00590
00591
00593
00594 void reassign(int n)
00595 { delete [] data; N = n; data = new T[n]; }
00596
00597
00598 void dumpflags()
00599 {
00600 for (int i=0; i<flag_N; i++)
00601 std::cout<<flag[i];
00602 std::cout << std::endl;
00603 }
00604
00605 friend par<T> &pow(par<T> &x, T t)
00606 {
00607 par<T> y(x.N);
00608 static par<T> z(x.N);
00609 z.reassign(x.N);
00610 y = t;
00611 z.par2_to_par( std::pow, x, y); return z;
00612 }
00613
00614 friend par<T> &pow(T t, par<T> &x)
00615 {
00616 par<T> y(x.N);
00617 static par<T> z(x.N);
00618 z.reassign(x.N);
00619 y = t;
00620 z.par2_to_par( std::pow, y, x); return z;
00621 }
00622
00623
00624
00626
00627 friend par<T> &rotate(par<T> &x, int amt)
00628 {
00629 static par<T> z(x.N); z.reassign(x.N);
00630 for (int i=0; i<x.N; i++)
00631 z.data[(i+amt+x.N)%x.N] = x.data[i];
00632 return z;
00633 }
00634
00635 friend par<T> &permute(par<T> &x, par<int> &y)
00636 {
00637 static par<T> z(x.N); z.reassign(x.N);
00638 for (int i=0; i<x.N; i++)
00639 z.data[y.data[i]%x.N] = x.data[i];
00640 return z;
00641 }
00642
00643 friend par<T> &pack(par<T> &x)
00644 {
00645 static par<T> z(x.N); z.reassign(x.N);
00646 int c=0;
00647 for (int i=0; i<x.N; i++)
00648 if (flag[i]) z.data[c++] = x.data[i];
00649 return z;
00650 }
00651
00652 };
00653
00654
00655 #endif
00656