您的位置:首页 > 其它

CodeChef SEPT17 简要题解

2017-09-11 18:30 459 查看
写完QGRID之后心力憔悴,根本不想动CHALLENGE。

CHEFSUM

签到。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (;  isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}

inline void Sol()
{
int n = Read(), p = 0, r = 1 << 30;
for (int i = 1, x; i <= n; i ++)
if ((x = Read()) < r)
r = x, p = i;
printf("%d\n", p);
}

int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
for (int T = Read(); T; T --)
Sol();
return 0;
}


MINPERM

签到。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (;  isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}

inline void Sol()
{
int n = Read();
if (n & 1)
{
for (int i = 1; i <= n - 3; i ++)
printf("%d ", (i - 1 ^ 1) + 1);
printf("%d %d %d\n", n - 1, n, n - 2);
}
else
{
for (int i = 1; i <= n - 2; i ++)
printf("%d ", (i - 1 ^ 1) + 1);
printf("%d %d\n", n, n - 1);
}
}

int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
for (int T = Read(); T; T --)
Sol();
return 0;
}


CHEFPDIG

签到。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (;  isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}

const int MAXN = 100005;

int cnt[10];
char s[MAXN];

inline void Sol()
{
mset(cnt, 0);
scanf("%s", s + 1);
for (int i = 1; s[i]; i ++)
cnt[s[i] - '0'] ++;
for (int i = 65; i <= 90; i ++)
{
if ((i / 10 ^ i % 10))
{
if (cnt[i / 10] && cnt[i % 10])
putchar(i);
}
else if (cnt[i / 10] >= 2)
putchar(i);
}
putchar(10);
}

int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
for (int T = Read(); T; T --)
Sol();
return 0;
}


SEACO

倒着做。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (;  isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}

const int MAXN = 100005;
const int mod = 1e9 + 7;

int n, m, typ[MAXN], l[MAXN], r[MAXN], a[MAXN], b[MAXN];

inline void Sol()
{
n = Read(), m = Read();
for (int i = 1; i <= m; i ++)
typ[i] = Read(), l[i] = Read(), r[i] = Read(), b[i] = 0;
for (int i = 1; i <= n; i ++)
a[i] = 0;
b[m + 1] = 1;
for (int i = m; i; i --)
{
b[i] = (b[i] + b[i + 1]) % mod;
if (typ[i] == 1)
a[l[i]] = (a[l[i]] + b[i]) % mod, a[r[i] + 1] = (a[r[i] + 1] - b[i] + mod) % mod;
else
b[r[i]] = (b[r[i]] + b[i]) % mod, b[l[i] - 1] = (b[l[i] - 1] - b[i] + mod) % mod;
}
for (int i = 1; i <= n; i ++)
printf("%d%c", a[i] = (a[i] + a[i - 1]) % mod, i == n ? '\n' : ' ');
}

int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
for (int T = Read(); T; T --)
Sol();
return 0;
}


FILLMTR

0的缩起来,1的连边,判二分图。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (;  isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}

const int MAXN = 100005;
const int MAXM = 1000005;

int n, m, u[MAXM], v[MAXM], w[MAXM], f[MAXN], c[MAXN];
vector <int> adj[MAXN];

inline int Find(int x)
{
while (x ^ f[x])
x = f[x] = f[f[x]];
return x;
}

inline bool Dfs(int x)
{
for (auto y : adj[x])
if (!~c[y])
{
c[y] = c[x] ^ 1;
if (!Dfs(y))
return false;
}
else if (c[y] == c[x])
return false;
return true;
}

inline void Sol()
{
n = Read(), m = Read();
for (int i = 1; i <= n; i ++)
f[i] = i, c[i] = -1, adj[i].clear();
for (int i = 1; i <= m; i ++)
u[i] = Read(), v[i] = Read(), w[i] = Read();
for (int i = 1; i <= m; i ++)
if (!w[i])
f[Find(u[i])] = Find(v[i]);
for (int i = 1; i <= m; i ++)
if (w[i])
{
if (Find(u[i]) == Find(v[i]))
return (void)puts("no");
adj[Find(u[i])].pb(Find(v[i]));
adj[Find(v[i])].pb(Find(u[i]));
}
for (int i = 1; i <= n; i ++)
if (!~c[i])
{
c[i] = 0;
if (!Dfs(i))
return (void)puts("no");
}
puts("yes");
}

int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
for (int T = Read(); T; T --)
Sol();
return 0;
}


WEASELTX

先把深度相同的缩起来,然后处理出f(i,j)表示i次操作后深度为j的是否有影响,注意到f(i,j)=f(i−1,j)xorf(i,j−1),然后分块。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline LL Read()
{
LL x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (;  isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}

const int MAXN = 262150;

int n, Q;
vector <int> adj[MAXN];
LL a[MAXN], b[MAXN], c[MAXN], d[515][515];

inline void Dfs(int x, int d, int p)
{
if (d)
b[d] ^= a[x];
for (auto y : adj[x])
if (y ^ p)
Dfs(y, d + 1, x);
}

int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
n = Read(), Q = Read();
for (int i = 1, x, y; i < n; i ++)
x = Read(), y = Read(), adj[x].pb(y), adj[y].pb(x);
for (int i = 0; i < n; i ++)
a[i] = Read();
Dfs(0, 0, -1);
for (int i = 0; i < 262144; i ++)
for (int j = ((i & 511) ^ 511), k = j; ; k = (k - 1 & j))
{
d[i >> 9][k] ^= b[i];
if (!k)
break;
}
for (int i = 0; i < 262144; i ++)
for (int j = (i >> 9 ^ 511), k = j; ; k = (k - 1 & j))
{
c[i] ^= d[k][i & 511];
if (!k)
break;
}
while (Q --)
{
LL x = Read();
if (!x)
printf("%lld\n", a[0]);
else
printf("%lld\n", a[0] ^ c[x - 1 & 262143]);
}
return 0;
}


SUMCUBE

管道取珠,难点在三元环计数,mm−−√做就好了。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (;  isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}

const int MAXN = 100005;
const int mod = 1e9 + 7;

namespace CircleCount
{
int e_cnt, ans, hed[MAXN], p[MAXN], v[MAXN], d[MAXN];
bool vis[MAXN];

inline bool Cmp(int x, int y)
{
return d[x] < d[y] || (d[x] == d[y] && x < y);
}

inline void Addedge(int x, int y)
{
p[++ e_cnt] = y; v[e_cnt] = hed[x]; hed[x] = e_cnt;
}

inline int Sol(int n, int m, int *x, int *y)
{
e_cnt = ans = 0;
for (int i = 1; i <= n; i ++)
hed[i] = d[i] = 0;
for (int i = 1; i <= m; i ++)
d[x[i]] ++, d[y[i]] ++;
for (int i = 1; i <= m; i ++)
if (Cmp(x[i], y[i]))
Addedge(x[i], y[i]);
else
Addedge(y[i], x[i]);
for (int x = 1; x <= n; x ++)
for (int i = hed[x]; i; i = v[i])
{
int y = p[i];
for (int j = hed[x]; j; j = v[j])
vis[p[j]] = 1;
for (int j = hed[y]; j; j = v[j])
ans += vis[p[j]];
for (int j = hed[x]; j; j = v[j])
vis[p[j]] = 0;
}
return 6LL * ans % mod;
}
}

int n, m, k, pw[MAXN], x[MAXN], y[MAXN], d[MAXN];

inline void Solve1()
{
printf("%d\n", 1LL * m * pw[n - 2] % mod);
}

inline void Solve2()
{
int ret = 0, w1 = m, w2 = 0, w3 = 1LL * m * m % mod;
for (int i = 1; i <= n; i ++)
d[i] = 0;
for (int i = 1; i <= m; i ++)
d[x[i]] ++, d[y[i]] ++;
for (int i = 1; i <= n; i ++)
w2 = (1LL * d[i] * (d[i] - 1) + w2) % mod;
w3 = (1LL * w3 - w2 - w1 + mod + mod) % mod;
ret = (1LL * w1 * pw[n - 2] + ret) % mod;
if (n >= 3)
ret = (1LL * w2 * pw[n - 3] + ret) % mod;
if (n >= 4)
ret = (1LL * w3 * pw[n - 4] + ret) % mod;
printf("%d\n", ret);
}

inline void Solve3()
{
int ret = 0, w1 = m, w2 = 0, w3 = 1LL * m * m % mod, w4 = 0, w5 = 0, w6 = CircleCount::Sol(n, m, x, y), w7 = 0, w8 = 1LL * m * m * m % mod;
for (int i = 1; i <= n; i ++)
d[i] = 0;
for (int i = 1; i <= m; i ++)
d[x[i]] ++, d[y[i]] ++;
for (int i = 1; i <= n; i ++)
w2 = (1LL * d[i] * (d[i] - 1) + w2) % mod, w4 = (1LL * d[i] * (d[i] - 1) * (d[i] - 2) + w4) % mod;
w3 = (1LL * w3 - w2 - w1 + mod + mod) % mod;
w2 = 3LL * w2 % mod;
w3 = 3LL * w3 % mod;
for (int i = 1; i <= m; i ++)
w5 = (1LL * (d[x[i]] - 1) * (d[y[i]] - 1) + w5) % mod;
w5 = (6LL * w5 - 3LL * w6 % mod + mod) % mod;
for (int i = 1; i <= n; i ++)
w7 = (3LL * d[i] * (d[i] - 1) * (m - d[i]) + w7) % mod;
w7 = ((1LL * w7 - 3LL * w6 - 2LL * w5) % mod + mod) % mod;
w8 = ((1LL * w8 - w1 - w2 - w3 - w4 - w5 - w6 - w7) % mod + mod) % mod;
cerr << w1 << " " << w2 << " " << w3 << " " << w4 << " " << w5 << " " << w6 << " " << w7 << " " << w8 << endl;
ret = (1LL * w1 * pw[n - 2] + ret) % mod;
if (n >= 3)
ret = (1LL * w2 * pw[n - 3] + ret) % mod;
if (n >= 4)
ret = (1LL * w3 * pw[n - 4] + ret) % mod;
if (n >= 4)
ret = (1LL * w4 * pw[n - 4] + ret) % mod;
if (n >= 4)
ret = (1LL * w5 * pw[n - 4] + ret) % mod;
if (n >= 3)
ret = (1LL * w6 * pw[n - 3] + ret) % mod;
if (n >= 5)
ret = (1LL * w7 * pw[n - 5] + ret) % mod;
if (n >= 6)
ret = (1LL * w8 * pw[n - 6] + ret) % mod;
printf("%d\n", ret);
}

inline void Sol()
{
n = Read(), m = Read(), k = Read();
for (int i = 1; i <= m; i ++)
x[i] = Read(), y[i] = Read();
if (k == 1)
return Solve1();
if (k == 2)
return Solve2();
return Solve3();
}

int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
pw[0] = 1;
for (int i = 1; i <= 100000; i ++)
pw[i] = (pw[i - 1] << 1) % mod;
for (int T = Read(); T; T --)
Sol();
return 0;
}


WEASELSC

DP,在单调栈上三分。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (;  isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}

const int MAXN = 100005;
const int MAXM = 55;

int n, m, tp, a[MAXN], st[MAXN];
LL f[MAXM][MAXN], ans;

inline void Dp(int k)
{
tp = 0;
for (int i = 1; i <= n; i ++)
{
while (tp && a[st[tp]] >= a[i])
tp --;
st[++ tp] = i;
int l = 0, r = tp - 1;
while (r - l > 4)
{
int m1 = l + (r - l) / 3, m2 = r - (r - l) / 3;
LL r1 = f[k - 1][st[m1]] + 1LL * a[st[m1 + 1]] * (i - st[m1]), r2 = f[k - 1][st[m2]] + 1LL * a[st[m2 + 1]] * (i - st[m2]);
if (r1 < r2)
l = m1;
else
r = m2;
}
for (int j = l; j <= r; j ++)
f[k][i] = max(f[k][i], f[k - 1][st[j]] + 1LL * a[st[j + 1]] * (i - st[j]));
ans = max(ans, f[k][i]);
}
}

inline void Sol()
{
n = Read(), m = Read() + 1, ans = 0;
for (int i = 1; i <= n; i ++)
a[i] = Read();
mset(f, 0);
for (int i = 1; i <= m; i ++)
Dp(i);
reverse(a + 1, a + n + 1);
mset(f, 0);
for (int i = 1; i <= m; i ++)
Dp(i);
printf("%lld\n", ans);
}

int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
for (int T = Read(); T; T --)
Sol();
return 0;
}


QGRID

这是个毒瘤题。

线段树维护一个区间的2m个端点两两之间最短路。

然后暴力。

这是个毒瘤题。

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <LL, LL> pLL;
typedef pair <int, int> pii;

template <typename T> inline bool Chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }

inline LL Read()
{
LL x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (;  isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}

const int MAXN = 400005;

int n, m, Q, rel[MAXN], idx[MAXN], pos[MAXN];
LL dow[3][MAXN], rig[3][MAXN], val[3][MAXN];

struct Node
{
int l, r;
LL dis[6][6], tag[6][6];
pLL pre[6][6];

friend Node operator + (const Node &a, const Node &b)
{
Node c;
LL dis[9][9];
pLL pre[9][9];
mset(dis, 127 / 7);
for (int i = 0; i < m * 2; i ++)
for (int j = 0; j < m * 2; j ++)
if (Chkmin(dis[i][j], a.dis[i][j]))
pre[i][j] = mp(1LL << i * m * 2 + j, 0);
for (int i = 0; i < m * 2; i ++)
for (int j = 0; j < m * 2; j ++)
if (Chkmin(dis[i + m][j + m], b.dis[i][j]))
pre[i + m][j + m] = mp(0, 1LL << i * m * 2 + j);
for (int k = 0; k < m * 3; k ++)
for (int i = 0; i < m * 3; i ++)
for (int j = 0; j < m * 3; j ++)
if (Chkmin(dis[i][j], dis[i][k] + dis[k][j]))
pre[i][j] = mp(pre[i][k].xx | pre[k][j].xx, pre[i][k].yy | pre[k][j].yy);
for (int i = 0; i < m * 2; i ++)
for (int j = 0; j < m * 2; j ++)
c.dis[i][j] = dis[i < m ? i : i + m][j < m ? j : j + m], c.pre[i][j] = pre[i < m ? i : i + m][j < m ? j : j + m], c.tag[i][j] = 0;
c.l = a.l, c.r = b.r;
return c;
}
} e[MAXN];

inline Node Init(int p)
{
Node c;
LL dis[6][6], pre[6][6];
mset(dis, 127 / 7);
for (int i = 0; i < m; i ++)
dis[i][i + m] = dis[i + m][i] = rig[i][p], pre[i][i + m] = pre[i + m][i] = 1LL << i;
for (int i = 0; i + 1 < m; i ++)
dis[i][i + 1] = dis[i + 1][i] = dow[i][p], pre[i][i + 1] = pre[i + 1][i] = 1LL << i + m;
for (int i = 0; i + 1 < m; i ++)
dis[i + m][i + m + 1] = dis[i + m + 1][i + m] = dow[i][p + 1], pre[i + m][i + m + 1] = pre[i + m + 1][i + m] = 1LL << i + m * 2;
for (int k = 0; k < m * 2; k ++)
for (int i = 0; i < m * 2; i ++)
for (int j = 0; j < m * 2; j ++)
if (Chkmin(dis[i][j], dis[i][k] + dis[k][j]))
pre[i][j] = pre[i][k] | pre[k][j];
for (int i = 0; i < m * 2; i ++)
for (int j = 0; j < m * 2; j ++)
c.dis[i][j] = dis[i][j], c.pre[i][j] = mp(pre[i][j], 0), c.tag[i][j] = 0;
c.l = c.r = p;
return c;
}

inline void Build(int x, int l, int r)
{
if (l == r)
return (void)(e[x] = Init(l), idx[x] = l, pos[l] = x);
int mid = l + r >> 1;
Build(x << 1, l, mid); Build(x << 1 | 1, mid + 1, r);
e[x] = e[x << 1] + e[x << 1 | 1];
}

inline void Pushdown(Node &x, Node &a, Node &b)
{
for (int i = 0; i < m * 2; i ++)
for (int j = 0; j < m * 2; j ++)
if (x.tag[i][j])
{
LL l = x.pre[i][j].xx, r = x.pre[i][j].yy;
while (l)
{
int tmp = rel[(l & -l) % MAXN];
a.tag[tmp / (m * 2)][tmp % (m * 2)] += x.tag[i][j];
l -= l & -l;
}
while (r)
{
int tmp = rel[(r & -r) % MAXN];
b.tag[tmp / (m * 2)][tmp % (m * 2)] += x.tag[i][j];
r -= r & -r;
}
x.tag[i][j] = 0;
}
}

inline void Pushdown(int x)
{
if (e[x].l ^ e[x].r)
return Pushdown(e[x], e[x << 1], e[x << 1 | 1]);
int p = idx[x];
for (int i = 0; i < m * 2; i ++)
for (int j = 0; j < m * 2; j ++)
if (i ^ j)
if (e[x].tag[i][j])
{
for (int k = 0; k < m; k ++)
if (e[x].pre[i][j].xx >> k & 1)
val[k][p] += e[x].tag[i][j], val[k][p + 1] += e[x].tag[i][j];
for (int k = 0; k < m - 1; k ++)
if (e[x].pre[i][j].xx >> k + m & 1)
val[k][p] += e[x].tag[i][j], val[k + 1][p] += e[x].tag[i][j];
for (int k = 0; k < m - 1; k ++)
if (e[x].pre[i][j].xx >> k + m * 2 & 1)
val[k][p + 1] += e[x].tag[i][j], val[k + 1][p + 1] += e[x].tag[i][j];
e[x].tag[i][j] = 0;
}
}

struct Info
{
int st[MAXN], tp;
Node sum[MAXN];

inline void Query(int x, int l, int r, int ql, int qr)
{
::Pushdown(x);
if (l == ql && r == qr)
return (void)(st[++ tp] = x);
int mid = l + r >> 1;
if (qr <= mid)
return Query(x << 1, l, mid, ql, qr);
if (ql > mid)
return Query(x << 1 | 1, mid + 1, r, ql, qr);
return Query(x << 1, l, mid, ql, mid), Query(x << 1 | 1, mid + 1, r, mid + 1, qr);
}

inline Node Get(int l, int r)
{
tp = 0;
if (l > r)
{
Node tmp;
mset(tmp.dis, 127 / 7);
return tmp;
}
Query(1, 0, n, l, r);
sum[1] = e[st[1]];
for (int i = 2; i <= tp; i ++)
sum[i] = sum[i - 1] + e[st[i]];
return sum[tp];
}

inline void Pushdown()
{
if (!tp)
return ;
for (int i = tp; i > 1; i --)
::Pushdown(sum[i], sum[i - 1], e[st[i]]);
e[st[1]] = sum[1];
}
} way[3];

inline void Modify()
{
int x1 = Read() - 1, y1 = Read(), x2 = Read() - 1, y2 = Read(), t1 = m * m * 4, t2 = t1 + m * m;
LL v = Read(), dis[6][6], pre[6][6];
mset(dis, 127 / 7);
val[x1][y1] += v; val[x2][y2] += v;
if (x1 == x2 && y1 == y2)
return ;
if (y1 > y2)
swap(x1, x2), swap(y1, y2);
Node a = way[0].Get(0, y1 - 1), b = way[1].Get(y1, y2 - 1), c = way[2].Get(y2, n);
if (y1 == y2)
for (int i = 0; i < m; i ++)
b.dis[i][i + m] = b.dis[i + m][i] = 0;
for (int i = 0; i < m * 2; i ++)
for (int j = 0; j < m * 2; j ++)
dis[i][j] = b.dis[i][j], pre[i][j] = 1LL << i * m * 2 + j;
for (int i = 0; i < m; i ++)
for (int j = 0; j < m; j ++)
if (Chkmin(dis[i][j], a.dis[i + m][j + m]))
pre[i][j] = 1LL << t1 + i * m + j;
for (int i = 0; i < m; i ++)
for (int j = 0; j < m; j ++)
if (Chkmin(dis[i + m][j + m], c.dis[i][j]))
pre[i + m][j + m] = 1LL << t2 + i * m + j;
for (int k = 0; k < m * 2; k ++)
for (int i = 0; i < m * 2; i ++)
for (int j = 0; j < m * 2; j ++)
if (Chkmin(dis[i][j], dis[i][k] + dis[k][j]))
pre[i][j] = pre[i][k] | pre[k][j];
LL tmp = pre[x1][x2 + m];
for (int i = 0; i < m * 2; i ++)
for (int j = 0; j < m * 2; j ++)
if (tmp >> i * m * 2 + j & 1)
way[1].sum[way[1].tp].tag[i][j] += v;
for (int i = 0; i < m; i ++)
for (int j = 0; j < m; j ++)
if (tmp >> t1 + i * m + j & 1)
way[0].sum[way[0].tp].tag[i + m][j + m] += v;
for (int i = 0; i < m; i ++)
for (int j = 0; j < m; j ++)
if (tmp >> t2 + i * m + j & 1)
way[2].sum[way[2].tp].tag[i][j] += v;
for (int i = 0; i < 3; i ++)
way[i].Pushdown();
}

inline void Query()
{
static int st[MAXN];
int x = Read() - 1, y = Read(), tp = 0;
for (int i = pos[y - 1]; i; i >>= 1)
st[++ tp] = i;
while (tp)
Pushdown(st[tp --]);
for (int i = pos[y]; i; i >>= 1)
st[++ tp] = i;
while (tp)
Pushdown(st[tp --]);
printf("%lld\n", val[x][y] / 2);
}

int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
mset(dow, 127 / 7);
mset(rig, 127 / 7);
for (int i = 0; i < 60; i ++)
rel[(1LL << i) % MAXN] = i;
m = Read(), n = Read(), Q = Read();
for (int i = 0; i < m - 1; i ++)
for (int j = 1; j <= n; j ++)
dow[i][j] = Read();
for (int i = 0; i < m; i ++)
for (int j = 1; j < n; j ++)
rig[i][j] = Read();
Build(1, 0, n);
while (Q --)
if (Read() == 1)
Modify();
else
Query();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: