策略游戏
#include<iostream>
#include<cstdio>
using namespace std;
const int inf=1<<30;
typedef long long ll;
ll a[100005],b[100005];int n,m,q,l1,r1,l2,r2,sa[100005],sb[100005],lg2[100005];
struct ST
{
ll st[100005][17];
int tp1,tp2;
ll query(int l,int r)
{
int k=lg2[r-l+1];
if(tp1==1) return min(st[l][k],st[r-(1<<k)+1][k]);
if(tp1==2) return max(st[l][k],st[r-(1<<k)+1][k]);
}
void build(int n,ll *f)
{
for(int i=1;i<=n;i++)
{
if(tp2==1) st[i][0]=(f[i]>=0?f[i]:(tp1==1?inf:-inf));
if(tp2==2) st[i][0]=(f[i]<0?-f[i]:(tp1==1?inf:-inf));
}
for(int i=1;i<=16;i++)
for(int j=1;j+(1<<i)-1<=n;j++)
{
if(tp1==1) st[j][i]=min(st[j][i-1],st[j+(1<<(i-1))][i-1]);
if(tp1==2) st[j][i]=max(st[j][i-1],st[j+(1<<(i-1))][i-1]);
}
}
} mxa1,mna1,mxa2,mna2,mxb1,mnb1,mxb2,mnb2;
int main()
{
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=m;i++) scanf("%lld",&b[i]);
for(int i=1;i<=n;i++) sa[i]=sa[i-1]+(a[i]<0);
for(int i=1;i<=m;i++) sb[i]=sb[i-1]+(b[i]<0);
for(int i=2;i<=100000;i++) lg2[i]=lg2[i/2]+1;
mxa1.tp1=2;mxa1.tp2=1;mxa1.build(n,a);
mxa2.tp1=2;mxa2.tp2=2;mxa2.build(n,a);
mna1.tp1=1;mna1.tp2=1;mna1.build(n,a);
mna2.tp1=1;mna2.tp2=2;mna2.build(n,a);
mxb1.tp1=2;mxb1.tp2=1;mxb1.build(m,b);
mxb2.tp1=2;mxb2.tp2=2;mxb2.build(m,b);
mnb1.tp1=1;mnb1.tp2=1;mnb1.build(m,b);
mnb2.tp1=1;mnb2.tp2=2;mnb2.build(m,b);
while(q--)
{
scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
int fa1=0,fa2=0,fb1=0,fb2=0;
if(sa[r1]-sa[l1-1]==r1-l1+1) fa1=1;
if(sa[r1]-sa[l1-1]==0) fa2=1;
if(sb[r2]-sb[l2-1]==r2-l2+1) fb1=1;
if(sb[r2]-sb[l2-1]==0) fb2=1;
ll amx1,amx2,amn1,amn2,bmx1,bmx2,bmn1,bmn2;
amx1=mxa1.query(l1,r1);
amx2=-mxa2.query(l1,r1);
amn1=mna1.query(l1,r1);
amn2=-mna2.query(l1,r1);
bmx1=mxb1.query(l2,r2);
bmx2=-mxb2.query(l2,r2);
bmn1=mnb1.query(l2,r2);
bmn2=-mnb2.query(l2,r2);
if(fa1)
{
if(fb1) printf("%lld\n",amx2*bmn2);
else printf("%lld\n",amn2*bmx1);
}
else if(fa2)
{
if(fb2) printf("%lld\n",amx1*bmn1);
else printf("%lld\n",amn1*bmx2);
}
else
{
if(fb1) printf("%lld\n",amx2*bmn2);
else if(fb2) printf("%lld\n",amx1*bmn1);
else printf("%lld\n",max(amn1*bmx2,amn2*bmx1));
}
}
return 0;
}
假期计划
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
typedef struct {
int nxt;
int end;
} Edge;
int cnt = 0;
int dis[2507][2507], head[2507], pos[2507][7];
ll s[2507], f[2507][2507];
Edge edge[20007];
queue<int> q;
inline void init(int n){
for (register int i = 1; i <= n; i++){
for (register int j = 1; j <= n; j++){
dis[i][j] = 0x7fffffff;
}
}
}
inline void add_edge(int start, int end){
cnt++;
edge[cnt].nxt = head[start];
head[start] = cnt;
edge[cnt].end = end;
}
void bfs(int start, int n){
dis[start][start] = 0;
q.push(start);
while (!q.empty()){
int cur = q.front();
q.pop();
for (register int i = head[cur]; i != 0; i = edge[i].nxt){
int x = edge[i].end;
if (dis[start][x] == 0x7fffffff){
dis[start][x] = dis[start][cur] + 1;
q.push(x);
}
}
}
}
int main(){
int n, m, k;
ll ans = 0;
cin >> n >> m >> k;
k++;
init(n);
for (register int i = 2; i <= n; i++){
cin >> s[i];
}
for (register int i = 1; i <= m; i++){
int x, y;
cin >> x >> y;
add_edge(x, y);
add_edge(y, x);
}
for (register int i = 1; i <= n; i++){
bfs(i, n);
}
for (register int i = 1; i <= n; i++){
for (register int j = 1; j <= n; j++){
if (i != j && dis[1][i] <= k && dis[i][j] <= k){
f[i][j] = s[i] + s[j];
} else {
f[i][j] = -4e18;
}
}
}
for (register int i = 2; i <= n; i++){
pos[i][1] = pos[i][2] = pos[i][3] = i;
for (register int j = 2; j <= n; j++){
if (f[pos[i][1]][i] < f[j][i]){
pos[i][3] = pos[i][2];
pos[i][2] = pos[i][1];
pos[i][1] = j;
} else if (f[pos[i][2]][i] < f[j][i]){
pos[i][3] = pos[i][2];
pos[i][2] = j;
} else if (f[pos[i][3]][i] < f[j][i]){
pos[i][3] = j;
}
}
}
for (register int i = 2; i <= n; i++){
for (register int j = 2; j <= n; j++){
if (i != j && dis[i][j] <= k){
for (register int x = 1; x <= 3; x++){
for (register int y = 1; y <= 3; y++){
if (pos[i][x] != j && pos[i][x] != pos[j][y] && pos[j][y] != i){
ans = max(ans, f[pos[i][x]][i] + f[pos[j][y]][j]);
break;
}
}
}
}
}
}
cout << ans;
return 0;
}
数据传输
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
typedef struct {
int nxt;
int end;
} Edge;
typedef struct Matrix_tag {
int n;
int m;
ll a[3][3];
Matrix_tag(){}
Matrix_tag(int n_, int m_){
n = n_;
m = m_;
for (register int i = 0; i <= n; i++){
for (register int j = 0; j <= m; j++){
a[i][j] = 4e18;
}
}
}
} Matrix;
int cnt = 0;
Matrix e;
int v[200007], a[200007], b[200007], head[200007], depth[200007], fa[200007][27], min_val[200007];
ll sum[200007];
Edge edge[400007];
Matrix each[200007], up[200007][18], down[200007][18];
Matrix operator *(Matrix a, Matrix b){
Matrix ans(a.n, b.m);
for (register int i = 0; i <= a.n; i++){
for (register int j = 0; j <= b.m; j++){
for (register int k = 0; k <= a.m; k++){
ans.a[i][j] = min(ans.a[i][j], a.a[i][k] + b.a[k][j]);
}
}
}
return ans;
}
inline void init(int n){
e = Matrix(n, n);
for (register int i = 0; i <= n; i++){
e.a[i][i] = 0;
}
}
inline void add_edge(int start, int end){
cnt++;
edge[cnt].nxt = head[start];
head[start] = cnt;
edge[cnt].end = end;
}
void dfs1(int u, int father){
int t;
depth[u] = depth[father] + 1;
t = log2(depth[u]);
fa[u][0] = father;
sum[u] = sum[father] + v[u];
for (register int i = 1; i <= t; i++){
fa[u][i] = fa[fa[u][i - 1]][i - 1];
}
for (register int i = head[u]; i != 0; i = edge[i].nxt){
int x = edge[i].end;
if (x != father) dfs1(x, u);
}
}
inline int lca(int u, int v){
if (depth[u] < depth[v]) swap(u, v);
while (depth[u] > depth[v]) u = fa[u][(int)log2(depth[u] - depth[v])];
if (u == v) return u;
for (register int i = log2(depth[u]); i >= 0; i--){
if (fa[u][i] != fa[v][i]){
u = fa[u][i];
v = fa[v][i];
}
}
return fa[u][0];
}
void dfs2(int u, int k){
int t = log2(depth[u]);
Matrix mat(k - 1, k - 1);
if (k == 2){
mat.a[0][0] = mat.a[1][0] = v[u];
mat.a[0][1] = 0;
} else {
mat.a[0][0] = mat.a[1][0] = mat.a[2][0] = v[u];
mat.a[0][1] = mat.a[1][2] = 0;
mat.a[1][1] = min_val[u];
}
each[u] = up[u][0] = down[u][0] = mat;
for (register int i = 1; i <= t; i++){
int x = fa[u][i - 1];
up[u][i] = up[u][i - 1] * up[x][i - 1];
down[u][i] = down[x][i - 1] * down[u][i - 1];
}
for (register int i = head[u]; i != 0; i = edge[i].nxt){
int x = edge[i].end;
if (x != fa[u][0]) dfs2(x, k);
}
}
Matrix get_up(int u, int v){
Matrix ans = e;
while (depth[u] > depth[v]){
int x = log2(depth[u] - depth[v]);
ans = ans * up[u][x];
u = fa[u][x];
}
if (u == v) ans = ans * each[u];
return ans;
}
Matrix get_down(int u, int v){
Matrix ans = e;
while (depth[u] > depth[v] + 1){
int x = log2(depth[u] - depth[v] - 1);
ans = down[u][x] * ans;
u = fa[u][x];
}
if (depth[u] > depth[v]) ans = each[u] * ans;
return ans;
}
int main(){
int n, q, k;
scanf("%d %d %d", &n, &q, &k);
for (register int i = 1; i <= n; i++){
scanf("%d", &v[i]);
}
for (register int i = 1; i < n; i++){
scanf("%d %d", &a[i], &b[i]);
add_edge(a[i], b[i]);
add_edge(b[i], a[i]);
}
dfs1(1, 0);
if (k == 1){
for (register int i = 1; i <= q; i++){
int s, t, cur_lca;
scanf("%d %d", &s, &t);
cur_lca = lca(s, t);
cout << sum[s] + sum[t] - sum[cur_lca] - sum[fa[cur_lca][0]] << endl;
}
} else {
init(k - 1);
for (register int i = 1; i <= n; i++){
min_val[i] = 0x7fffffff;
}
for (register int i = 1; i < n; i++){
min_val[a[i]] = min(min_val[a[i]], v[b[i]]);
min_val[b[i]] = min(min_val[b[i]], v[a[i]]);
}
dfs2(1, k);
for (register int i = 1; i <= q; i++){
int s, t;
scanf("%d %d", &s, &t);
int cur_lca = lca(s, t);
Matrix mat;
if (cur_lca == s){
mat = e;
} else {
mat = get_up(fa[s][0], cur_lca);
}
if (cur_lca != t) mat = mat * get_down(t, cur_lca);
cout << mat.a[0][0] + v[s] << endl;
}
}
return 0;
}
星战
#include <bits/stdc++.h>
#define N 500010
using namespace std;
int n , m , q , i;
unsigned long long sum , ans , val[N] , pos[N] , pos2[N];
pair<int , int> e[N];
int main()
{
srand(time(0)) , cin >> n >> m;
for(i = 1;i <= n;i++)
val[i] = rand() , sum += val[i];
for(i = 1;i <= m;i++)
{
cin >> e[i].first >> e[i].second;
ans += val[e[i].first];
pos[e[i].second] += val[e[i].first];
}
for(i = 1;i <= n;i++)
pos2[i] = pos[i];
cin >> q;
for(i = 1;i <= q;i++)
{
int opt; cin >> opt; int op = (opt == 1 || opt == 2 ? -1 : 1);
if(opt == 1 || opt == 3)
{
int x , y; cin >> x >> y;
if(opt == 1) pos[y] -= val[x] , ans -= val[x];
else pos[y] += val[x] , ans += val[x];
}
if(opt == 2 || opt == 4)
{
int x; cin >> x;
if(opt == 2) ans -= pos[x] , pos[x] = 0;
else ans += pos2[x] - pos[x] , pos[x] = pos2[x];
}
puts(sum == ans ? "YES" : "NO");
}
}