statement:https://www.jisuanke.com/contest/5527
赛中过题: B D F G H I K N
A.Girls Band Party
处理完输入后似乎就是一个简单的01背包,写的时候弱智了..
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
typedef pair<int, int> pii;
#define fi first
#define se second
#define empb emplace_back
#define all(x) (x).begin(),(x).end()
const int N = 100010;
int a[N][3], w[N][2];
int b[5], c;
map<string, int> id;
int tot;
string s;
int getid() {
cin >> s;
if(id.count(s)) return id[s];
return id[s] = ++tot;
}
int dp[6][6][6];
int main() {
#ifdef local
freopen("in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int _; cin >> _;
while(_--) {
int n; cin >> n;
id.clear(); tot = 0;
for(int i = 0; i < n; i++) {
a[i][0] = getid();
a[i][1] = getid();
cin >> a[i][2];
}
for(int i = 0; i < 5; i++) {
b[i] = getid();
}
c = getid();
memset(w, 0, (tot + 1) * sizeof(w[0]));
for (int i = 0; i < n; i++) {
int f = a[i][1] == c;
w[a[i][0]][f] = max(w[a[i][0]][f], a[i][2]);
}
memset(dp, -1, sizeof dp);
dp[0][0][0] = 0;
for(int i = 1; i <= tot; i++) {
if(!w[i][0] && !w[i][1]) continue;
int x = 0;
for(int j = 0; j < 5; j++) {
if(i == b[j]) x = 1;
}
for(int j = 5; j >= 1; j--)
for(int k = j; k >= x; k--)
for(int l = j; l >= 0; l--)
for(int y = 0; y < 2; y++) {
if(!w[i][y] || l < y || dp[j-1][k-x][l-y]==-1) continue;
dp[j][k][l] = max(dp[j][k][l], dp[j-1][k-x][l-y]+w[i][y]);
}
}
int ans = 0;
for(int i = 0; i <= 5; i++) {
for(int j = 0; j <= 5; j++) {
ans = max(ans, dp[5][i][j]*(10+i+j*2)/10);
}
}
cout << ans << '\n';
}
return 0;
}
E.Xor tree
设 ,则
.
枚举套用长链剖分,总复杂度为
,其中
.
计蒜客评测机非常不稳定,卡了很久才过.
#include<bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define fi first
#define se second
#define empb emplace_back
#define all(x) (x).begin(),(x).end()
const int N = 100010;
struct node_t {
int a[4];
int &operator [](int i) { return a[i];}
void init(int msk) {
memset(a, 0, sizeof a);
a[msk] = 1;
}
node_t& operator += (const node_t &rhs) {
for(int i = 0; i < 4; i++) a[i] += rhs.a[i];
return *this;
}
node_t& operator -= (const node_t &rhs) {
for(int i = 0; i < 4; i++) a[i] -= rhs.a[i];
return *this;
}
};
vector<int> E[N];
int n, k;
int a[N], dep[N], son[N];
void prepare(int u) {
for(auto &v : E[u]) {
prepare(v);
if(dep[son[u]] < dep[v]) son[u] = v;
}
dep[u] = dep[son[u]] + 1;
}
node_t pool[N], *pt = pool, *dp[N];
ull res[N];
void dfs(int u, int i, int j) {
dp[u] = pt++;
int msk = (a[u]>>i&1)<<1|(a[u]>>j&1);
dp[u]->init(msk);
if(son[u]) dfs(son[u], i, j);
for(auto &v : E[u]) {
if(v == son[u]) continue;
dfs(v, i, j);
for(int l = 0; l <= dep[v]; l++) {
dp[u][l + 1] += dp[v][l];
}
}
if(dep[u] > 0) dp[u][0] += dp[u][1];
node_t ans = dp[u][0];
if(dep[u] > k) ans -= dp[u][k + 1];
res[u] += (1ull << i + j + (i != j)) * ((ll)ans[0] * ans[3] + (ll)ans[1] * ans[2]);
}
int main() {
#ifdef local
freopen("in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
dep[0] = -1;
cin >> n >> k;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 2, f; i <= n; i++) {
cin >> f;
E[f].push_back(i);
}
prepare(1);
for(int i = 0; i < 30; i++) {
for(int j = 0; j <= i; j++) {
pt = pool;
dfs(1, i, j);
}
}
for(int i = 1; i <= n; i++) {
cout << res[i] << '\n';
}
return 0;
}

京公网安备 11010502036488号