Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long LL;
- typedef pair<int, int> PII;
- typedef vector<int> VI;
- typedef vector<double> VD;
- #define MP make_pair
- #define PB push_back
- #define X first
- #define Y second
- #define FOR(i, a, b) for(int i = (a); i < (b); ++i)
- #define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); --i)
- #define ITER(it, a) for(__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
- #define ALL(a) a.begin(), a.end()
- #define SZ(a) (int)((a).size())
- #define FILL(a, value) memset(a, value, sizeof(a))
- #define debug(a) cout << #a << " = " << a << endl;
- const double PI = acos(-1.0);
- const LL INF = 1e9;
- const LL LINF = INF * INF;
- mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- int dp[21][1 << 22];
- int was[61];
- int mask1 , mask2 , lenM1 , lenM2;
- void findMasks(int len , int mask , int bit)
- {
- mask2 = (mask >> (bit + 1));
- mask1 = mask ^ (mask2 << (bit + 1));
- mask2 <<= 1;
- if((mask1 >> bit) & 1)
- mask1 ^= (1 << bit);
- lenM1 = bit - 1;
- lenM2 = len - bit;
- }
- void updYe(int len , int mask , int bit)
- {
- findMasks(len , mask , bit);
- was[dp[lenM1][mask1] ^ dp[lenM2][mask2]] = 1;
- was[dp[len][mask ^ (1 << bit)]] = 1;
- }
- void updNema(int len , int mask , int bit)
- {
- if(bit == 1 && (mask & 1))
- return;
- if(bit == len && (mask & (1 << (len + 1))))
- return;
- findMasks(len , mask , bit);
- mask2 |= 1;
- mask1 |= (1 << (lenM1 + 1));
- was[dp[lenM1][mask1] ^ dp[lenM2][mask2]] = 1;
- }
- #define ll long long
- #define ld long double
- #define vll vector <ll>
- #define vvll vector <vll>
- #define pll pair <ll, ll>
- #define rep(i, a, b) for(ll i = a; i < b; i++)
- #define per(i, a, b) for(ll i = a - 1; i >= b; --i)
- #define endl "\n"
- #define pb push_back
- #define pf push_front
- #define all(v) (v).begin(), (v).end()
- #define rall(v) (v).rbegin(), (v).rend()
- #define sorta(v) sort(all(v))
- #define sortd(v) sort(rall(v))
- #define vld vector<ld>
- #define debug if (1)
- #define test if(1)
- #define log(val) debug {cout << "\n" << #val << ": " << val << "\n";}
- #define ios ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
- #define mod (ll)(1e9 + 7)
- ostream & operator << (ostream & out, vll & a) {
- for(auto i : a) out << i << " ";
- return out;
- }
- istream & operator >> (istream & in, vll & a) {
- for(auto &i : a) in >> i;
- return in;
- }
- long long dp1[21][1 << 22];
- ll used[50];
- ll bits[22];
- void precalc() {
- bits[0] = 1;
- rep(i, 1, 22) {
- bits[i] = (bits[i - 1] + 1) * 2 - 1;
- }
- rep(n, 1, 21) {
- per(mask, (1 << n), 0) {
- fill(used, used + 2 * n + 2, 0);
- rep(i, 0, n) {
- if((mask & (1 << i))) {
- ll x1 = 0, x2 = 0;
- if(i + 1 < n) {
- if(mask & (1 << (i + 1))) {
- x2 = (i + 2 < n ? dp1[n - i - 2][mask >> (i + 2)] : 0);
- } else {
- x2 = 1 ^ (i + 2 < n ? dp1[n - i - 2][mask >> (i + 2)] : 0);
- }
- }
- if(i - 1 >= 0) {
- if(mask & (1 << (i - 1))) {
- x1 = (i - 2 >= 0 ? dp1[i - 2 + 1][mask & bits[i - 2]] : 0);
- } else {
- x1 = 1 ^ (i - 2 >= 0 ? dp1[i - 2 + 1][mask & bits[i - 2]] : 0);
- }
- }
- /*if(n == 2 && mask == 2) {
- log(i);
- cout << "First : " << endl;
- cout << x1 << " " << x2 << endl;
- }*/
- used[x1 ^ x2] = 1;
- } else {
- /*if(n == 2 && mask == 2) {
- log(i);
- cout << "Second : " << endl;
- cout << dp1[n][mask ^ (1 << i)] << " " << ((i - 1 >= 0 ? dp1[i - 1 + 1][mask & bits[i - 1]] : 0) ^ (i + 1 < n ? dp1[n - i - 1][mask >> (i + 1)] : 0)) << endl;
- }*/
- used[dp1[n][mask ^ (1 << i)]] = 1;
- used[(i - 1 >= 0 ? dp1[i - 1 + 1][mask & bits[i - 1]] : 0) ^ (i + 1 < n ? dp1[n - i - 1][mask >> (i + 1)] : 0)] = 1;
- }
- }
- ll in = 0;
- while(used[in])in++;
- dp1[n][mask] = in;
- }
- }
- }
- ll solve(string & s) {
- ll ans = 0;
- ll cur = 0;
- ll cnt = 0;
- ll n = s.size();
- rep(i, 0, s.size()) {
- if(s[i] == 'A') {
- if(i - 1 >= 0 && !(i - 2 >= 0 && s[i - 2] == 'A')) {
- if(s[i - 1] == 'B' || s[i - 1] == 'C') {
- if(cnt - 2 >= 0)
- ans ^= dp1[cnt - 1][cur & bits[cnt - 2]];
- } else if(s[i - 1] == 'D') {
- ans ^= 1;
- if(cnt - 2 >= 0)
- ans ^= dp1[cnt - 1][cur & bits[cnt - 2]];
- }
- }
- cnt = 0;
- cur = 0;
- if(i + 1 < n) {
- if(s[i + 1] == 'D') {
- ans ^= 1;
- }
- }
- i++;
- } else if(s[i] == 'B') {
- cur |= (1 << cnt);
- cnt++;
- } else if(s[i] == 'D') {
- cnt++;
- } else {
- ans ^= dp1[cnt][cur];
- cnt = 0;
- cur = 0;
- }
- }
- if(cnt != 0) {
- ans ^= dp1[cnt][cur];
- }
- return ans;
- }
- string getS(ll num) {
- test {
- if(!num) return ".I.";
- else if(num == 1) return (rand() % 2 == 0 ? "II." : ".II");
- else if(num == 2) return "III";
- else return "I.I";
- }
- else {
- string s;
- cin >> s;
- return s;
- }
- }
- int main()
- {
- //ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
- //freopen("In.txt", "r", stdin);
- //freopen("In.txt", "w", stdout);
- for(int len = 1; len <= 20; len++)
- {
- for(int mask = 0; mask < (1 << (len + 2)); mask++)
- {
- memset(was , 0 , sizeof was);
- for(int bit = 1; bit <= len; bit++)
- {
- if((mask >> bit) & 1)
- updYe(len , mask , bit);
- else
- updNema(len , mask , bit);
- }
- int ans = 0;
- while(was[ans])
- ans++;
- dp[len][mask] = ans;
- }
- }
- precalc();
- cout << "start : " << endl;
- while(true) {
- int n;
- test n = rand() % 10 + 1;
- else cin >> n;
- int mask = 0;
- int len = 0;
- int xrSum = 0;
- string cur = "";
- string prevs = "";
- for(int i = 0; i < n; i++)
- {
- string s;
- s = getS(rand() % 4);
- if(s == prevs && s == ".I.") s = "III";
- prevs = s;
- int type;
- if(s == ".I.") {
- type = 1;
- cur += "A";
- }
- else if (s == "II." || s == ".II") {
- type = 2;
- cur += "B";
- }
- else if (s == "III") {
- type = 3;
- cur += "D";
- }
- else {
- type = 4;
- cur += "C";
- }
- if(type == 1)
- {
- mask |= (1 << (len + 1));
- xrSum ^= dp[len][mask];
- len = 0;
- mask = 1;
- }
- if(type == 4)
- {
- xrSum ^= dp[len][mask];
- len = 0;
- mask = 0;
- }
- if(type == 3)
- {
- len++;
- mask |= (1 << len);
- }
- if(type == 2)
- len++;
- }
- xrSum ^= dp[len][mask];
- //cout << xrSum << endl;
- //cout << solve(cur) << endl;
- //cout << xrSum << endl;
- ll cur1 = xrSum, cur2 = solve(cur);
- cout << cur << " " << cur1 << " " << cur2 << endl;
- /*test{}else{
- cout << cur1 << " " << cur2 << endl;
- }*/
- if(cur1 != cur2) {
- cout << cur1 << ' ' << cur2 << " " << cur << endl;
- return 0;
- }
- }
- //cerr << "Time elapsed: " << clock() / (double)CLOCKS_PER_SEC << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement