张hao同学同学写的题解,代翻为博客~
E.
LCS模版题,比较测试样例与正确顺序的最长子序列。
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
{
if(a[i] == b[j])
{
dp[i][j] = dp[i-1][j-1] + 1;
}
else
{
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
}
F.
DFS,尝试从每个点出发,然后dfs,但这里需要再创建一个状态数组来保存已遍历过的情况,然后再在dfs其他点之前判断当前点状态是否为0,
#include<bits/stdc++.h>
using namespace std;
int f[110][110];
int a[110][110];
int dx[4]= {
0,0,+1,-1};
int dy[4]= {
+1,-1,0,0};
int r,c,t=0,j;
int dfs(int x,int y) {
if(f[x][y]) return f[x][y];
for(int i=0; i<4; i++) {
int xx=x+dx[i];
int yy=y+dy[i];
if(xx>=1&&yy>=1&&xx<=r&&yy<=c&&a[xx][yy]<a[x][y])
f[x][y]=max(f[x][y],dfs(xx,yy)+1);
}
return f[x][y];
}
int main() {
cin>>r>>c;
for(int i=1; i<=r; i++) {
for(j=1; j<=c; j++) {
cin>>a[i][j];
}
}
t=0;
for(int i=1; i<=r; i++) {
for(j=1; j<=c; j++) {
t=max(t,dfs(i,j));
}
}
cout<<t+1;
return 0;
}
dx,dy用来存放一个点向四个方向移动,同时在引用dfs函数时,i不能事先定义,否则for循环的i与dfs函数里面的i起冲突。
G.
事件 1,任意节点 y 会增加 w − d i s t ( x , y ) 该式子可以转化为:
w − d i s t ( x , y ) = w − ( d [ x ] + d [ y ] − 2 *d [ l c a ( x , y ) ] )
因为 w − d [ x ] 与节点 y无关,可以设sum记录每次的 w − d [ x ] 之和,在询问的时候加上即;
而d[y]仅与节点y有关,因此可以设 num记录事件1的数量,在询问的时候减去num⋅d[y]即可;
对于d[lca(x,y)],可以通过树剖维护,每次将x到根节点的路径上的点加1,这样y到根节点的路径上的点值之和为所有d[lca(x,y)]之和。
事件 2 ,用delta[x]记录事件节点 x在事件 2 2 2中减去的值之和,如果询问得到的x的当前值 val大于 0,那么delta[x]加上val,在求 x当前值时要减去delta[x]。
事件3,根据事件1,2,节点 x的值为sum−num⋅d[x]+2*(x到根路径上的点值之和)−delta[x]
#include<bits/stdc++.h>
#define pi(a) printf("%d\n",a)
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
using namespace std;
inline int qr() {
int f = 0, fu = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-')fu = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
f = (f << 3) + (f << 1) + c - 48;
c = getchar();
}
return f * fu;
}
const int N = 5e4 + 10;
int head[N], ver[N << 1], Next[N << 1], tot;
struct Seg_Tree {
struct T {
int l, r, ans, add;
} t[N * 4];
void build(int p, int l, int r) {
t[p].l = l, t[p].r = r, t[p].ans = t[p].add = 0;
if (l == r)return;
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
}
void spread(int p) {
if (t[p].add) {
t[p << 1].ans += t[p].add * (t[p << 1].r - t[p << 1].l + 1);
t[p << 1 | 1].ans += t[p].add * (t[p << 1 | 1].r - t[p << 1 | 1].l + 1);
t[p << 1].add += t[p].add;
t[p << 1 | 1].add += t[p].add;
t[p].add = 0;
}
}
void change(int p, int l, int r, int c) {
if (l <= t[p].l && t[p].r <= r) {
t[p].add += c;
t[p].ans += c * (t[p].r - t[p].l + 1);
return;
}
spread(p);
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid)change(p << 1, l, r, c);
if (r > mid)change(p << 1 | 1, l, r, c);
t[p].ans = t[p << 1].ans + t[p << 1 | 1].ans;
}
int ask(int p, int l, int r) {
if (l <= t[p].l && r >= t[p].r)return t[p].ans;
spread(p);
int mid = (t[p].l + t[p].r) >> 1;
int val = 0;
if (l <= mid)val += ask(p << 1, l, r);
if (r > mid)val += ask(p << 1 | 1, l, r);
return val;
}
} sgt;
struct Tree {
int d[N], fa[N], siz[N], son[N], dfn[N], rnk[N], top[N], num;
void dfs1(int x, int f) {
siz[x] = 1, son[x] = 0;
reps(x) {
int y = ver[i];
if (y == f)continue;
fa[y] = x, d[y] = d[x] + 1, dfs1(y, x), siz[x] += siz[y];
if (siz[y] > siz[son[x]]) son[x] = y;
}
}
void dfs2(int x, int p) {
top[x] = p, dfn[x] = ++num, rnk[num] = x;
if (son[x]) dfs2(son[x], p);
reps(x) {
int y = ver[i];
if (fa[x] == y || y == son[x])continue;
dfs2(y, y);
}
}
void updr(int x, int y, int v) {
while (top[x] != top[y]) {
if (d[top[x]] < d[top[y]])swap(x, y);
sgt.change(1, dfn[top[x]], dfn[x], v);
x = fa[top[x]];
}
if (d[x] > d[y])swap(x, y);
sgt.change(1, dfn[x], dfn[y], v);
}
int quer(int x, int y) {
int ans = 0;
while (top[x] != top[y]) {
if (d[top[x]] < d[top[y]])swap(x, y);
ans += sgt.ask(1, dfn[top[x]], dfn[x]);
x = fa[top[x]];
}
if (d[x] > d[y])swap(x, y);
ans += sgt.ask(1, dfn[x], dfn[y]);
return ans;
}
inline void init(int n, int r) {
d[r] = 1, num = 0, dfs1(r, 0), dfs2(r, r), sgt.build(1, 1, n);
}
} tr;
int d[N], sum, num, n, m, T;
inline void init() {
tot = sum = num = 0;
repi(i, 1, n)head[i] = d[i] = 0;
}
inline void add(int x, int y) {
ver[++tot] = y;
Next[tot] = head[x];
head[x] = tot;
}
inline int ask(int x) {
return sum - tr.d[x] * num + 2 * tr.quer(x, 1) - d[x];
}
int main() {
T = qr();
while (T--) {
n = qr(), m = qr();
init();
repi(i, 1, n - 1) {
int x = qr(), y = qr();
add(x, y), add(y, x);
}
tr.init(n, 1);
while (m--) {
int op = qr(), x = qr();
if (op == 1) {
int w = qr();
sum += w - tr.d[x], num++;
tr.updr(x, 1, 1);
} else if (op == 2) {
int val = ask(x);
if (val > 0)d[x] += val;
} else
pi(ask(x));
}
}
return 0;
}
H.
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7+7;
int a[maxn];
int f(int x) {
int i;
for(i=2; i*i<=x; i++) {
if(x%i==0)
return 0;
}
return 1;
}
int main() {
int a,i,j,max,s=0;
while(cin>>a) {
s=0;
if(a==0)
return 0;
for(i=3; i<=a; i+=2) {
if(f(i)==1&&f(a-i)==1) {
printf("%d = %d + %d\n",a,i,a-i);
s++;
break;
}
}
}
if(!s)
cout<<" Goldbach's conjecture is wrong."<<endl;
return 0;
}