标签:+= pop efi logs 错误 string ace a* sizeof
因为去年阴影太大拖到现在才做..
下面的题号都是uoj上的啊
去年对此一窍不通
但现在我想到了长链剖分、线段树合并
硬是不知道怎么$O(n)$处理询问我好菜啊
维护$w_x-dep_x$和$w_x+dep_x$,分别对应往上走的链和往下走的链
题目就是要找子树内与当前根相同的值的个数
那么在下去子树前先记录现在的值,再用做完子树后的值减去它就行了
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
const int Maxn = 300010;
const int N = 300000;
const int lg = 20;
struct node {
int y, next;
}a[Maxn<<1]; int first[Maxn], len;
void ins(int x, int y) {
len++;
a[len].y = y;
a[len].next = first[x]; first[x] = len;
}
int n, m;
int w[Maxn], dep[Maxn], fa[Maxn][lg];
int ans[Maxn];
void dfs(int x) {
for(int i = 1; i < lg; i++) fa[x][i] = fa[fa[x][i-1]][i-1];
for(int k = first[x]; k; k = a[k].next){
int y = a[k].y;
if(y == fa[x][0]) continue;
fa[y][0] = x; dep[y] = dep[x]+1;
dfs(y);
}
}
int getlca(int x, int y) {
if(dep[x] < dep[y]) swap(x, y);
for(int i = lg-1; i >= 0; i--) if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];
if(x == y) return x;
for(int i = lg-1; i >= 0; i--) if(fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
return fa[x][0];
}
struct qnode {
int x, op, s;
qnode(int x = 0, int op = 0, int s = 0) : x(x), op(op), s(s) {}
};
vector <qnode> vec[Maxn];
int s[2][Maxn<<1];
void getans(int x) {
int last0 = s[0][w[x]+dep[x]], last1 = s[1][w[x]-dep[x]+N];
int sz = vec[x].size();
for(int i = 0; i < sz; i++){
qnode o = vec[x][i];
s[o.op][o.x] += o.s;
}
for(int k = first[x]; k; k = a[k].next){
int y = a[k].y;
if(y == fa[x][0]) continue;
getans(y);
}
ans[x] += s[0][w[x]+dep[x]]-last0+s[1][w[x]-dep[x]+N]-last1;
}
int main() {
int i, j, k;
scanf("%d%d", &n, &m);
for(i = 1; i < n; i++){
int x, y;
scanf("%d%d", &x, &y);
ins(x, y); ins(y, x);
}
dep[1] = 1;
dfs(1);
for(i = 1; i <= n; i++) scanf("%d", &w[i]);
for(i = 1; i <= m; i++){
int x, y;
scanf("%d%d", &x, &y);
int lca = getlca(x, y);
if(dep[x]-dep[lca] == w[lca]) ans[lca]--;
vec[x].push_back(qnode(dep[x], 0, 1)); vec[fa[lca][0]].push_back(qnode(dep[x], 0, -1));
vec[y].push_back(qnode(dep[x]-2*dep[lca]+N, 1, 1)); vec[fa[lca][0]].push_back(qnode(dep[x]-2*dep[lca]+N, 1, -1));
}
getans(1);
for(i = 1; i <= n; i++) printf("%d%c", ans[i], i==n?‘\n‘:‘ ‘);
return 0;
}
去年想到dp方程不敢写,真的菜
$f_{i,j,0/1}$表示前$i$个用了$j$次申请,第$i-1$次有没有申请
很好转移的
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int Maxn = 2010;
const int Maxm = 310;
const int inf = 0x7fffffff;
int n, m, v, e;
double f[2][Maxn][2];
int dis[Maxm][Maxm];
int c[Maxn], d[Maxn]; double p[Maxn];
int _min(int x, int y) { return x < y ? x : y; }
double _min(double x, double y) { return x < y ? x : y; }
int main() {
int i, j, k;
scanf("%d%d%d%d", &n, &m, &v, &e);
for(i = 1; i <= n; i++) scanf("%d", &c[i]);
for(i = 1; i <= n; i++) scanf("%d", &d[i]);
for(i = 1; i <= n; i++) scanf("%lf", &p[i]);
for(i = 1; i <= v; i++) for(j = 1; j <= v; j++) dis[i][j] = inf;
for(i = 1; i <= e; i++){
int x, y, d;
scanf("%d%d%d", &x, &y, &d);
dis[x][y] = dis[y][x] = _min(d, dis[x][y]);
}
for(k = 1; k <= v; k++){
for(i = 1; i <= v; i++) if(dis[i][k] != inf && i != k){
for(j = 1; j <= v; j++) if(dis[k][j] != inf && i != j && j != k){
dis[i][j] = _min(dis[i][j], dis[i][k]+dis[k][j]);
}
}
}
for(i = 1; i <= v; i++) dis[i][i] = 0;
for(i = 0; i <= m; i++) f[0][i][0] = f[0][i][1] = inf;
f[0][0][0] = 0; f[0][1][1] = 0;
int st = 0;
for(k = 2; k <= n; k++){
st ^= 1;
for(i = 0; i <= m; i++){
f[st][i][0] = _min(f[st^1][i][0]+dis[c[k-1]][c[k]], f[st^1][i][1]+p[k-1]*dis[d[k-1]][c[k]]+(1-p[k-1])*dis[c[k-1]][c[k]]);
if(i) f[st][i][1] = _min(f[st^1][i-1][0]+p[k]*dis[c[k-1]][d[k]]+(1-p[k])*dis[c[k-1]][c[k]],
f[st^1][i-1][1]+p[k]*p[k-1]*dis[d[k-1]][d[k]]+p[k]*(1-p[k-1])*dis[c[k-1]][d[k]]+
(1-p[k])*p[k-1]*dis[d[k-1]][c[k]]+(1-p[k])*(1-p[k-1])*dis[c[k-1]][c[k]]);
else f[st][i][1] = inf;
}
}
double ans = inf;
for(i = 0; i <= m; i++) ans = _min(ans, _min(f[st][i][0], f[st][i][1]));
printf("%.2lf\n", ans);
return 0;
}
去年没想到
用三个队列维护就行了
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#define LL long long
using namespace std;
const LL Maxn = 100010;
const LL inf = (LL)1<<60;
LL a[Maxn];
LL n, m, q, u, v, t;
queue <LL> que[3];
int main() {
LL i, j, k;
scanf("%lld%lld%lld%lld%lld%lld", &n, &m, &q, &u, &v, &t);
for(i = 1; i <= n; i++) scanf("%lld", &a[i]);
sort(a+1, a+n+1);
for(i = n; i >= 1; i--) que[0].push(a[i]);
for(i = 1; i <= m; i++){
LL x0, x1, x2;
if(!que[0].empty()) x0 = que[0].front(); else x0 = -inf;
if(!que[1].empty()) x1 = que[1].front(); else x1 = -inf;
if(!que[2].empty()) x2 = que[2].front(); else x2 = -inf;
LL nl, l1, l2;
if(x0 >= x1 && x0 >= x2){
nl = x0+(i-1)*q; que[0].pop();
l1 = nl*u/v, l2 = nl-l1;
que[1].push(l1-i*q); que[2].push(l2-i*q);
} else if(x1 >= x0 && x1 >= x2){
nl = x1+(i-1)*q; que[1].pop();
l1 = nl*u/v, l2 = nl-l1;
que[1].push(l1-i*q); que[2].push(l2-i*q);
} else {
nl = x2+(i-1)*q; que[2].pop();
l1 = nl*u/v, l2 = nl-l1;
que[1].push(l1-i*q); que[2].push(l2-i*q);
}
if(i%t == 0) printf("%lld ", nl);
}
printf("\n");
for(i = 1; i <= n+m; i++){
LL x0, x1, x2;
if(!que[0].empty()) x0 = que[0].front(); else x0 = -inf;
if(!que[1].empty()) x1 = que[1].front(); else x1 = -inf;
if(!que[2].empty()) x2 = que[2].front(); else x2 = -inf;
LL nl, l1, l2;
if(x0 >= x1 && x0 >= x2){
nl = x0+m*q; que[0].pop();
} else if(x1 >= x0 && x1 >= x2){
nl = x1+m*q; que[1].pop();
} else {
nl = x2+m*q; que[2].pop();
}
if(i%t == 0) printf("%lld ", nl);
}
return 0;
}
去年最大的阴影,想的$O(2^nn^2)$写的$O(2^nn^3)$强行卡掉自己15分
预处理出某两个点为抛物线经过的点
然后dp就行了
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define eps 1e-10
using namespace std;
const int Maxn = 20;
int f[1<<18], n, m;
int g[Maxn][Maxn];
double X[Maxn], Y[Maxn];
double _abs(double x) { return x < 0 ? -x : x; }
double zero(double x) { return _abs(x) < eps ? 1 : 0; }
void down(int &x, int y) { if(x > y) x = y; }
int main() {
int i, j, k;
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
for(i = 0; i < n; i++) scanf("%lf%lf", &X[i], &Y[i]);
for(i = 0; i < n; i++){
for(j = i+1; j < n; j++){
g[i][j] = 0;
if(zero(X[i]-X[j]) || zero(Y[i]/X[i]-Y[j]/X[j])) continue;
double A = (Y[i]*X[j]-Y[j]*X[i])/(X[i]*X[j]*(X[i]-X[j])), B = (Y[i]*X[j]*X[j]-Y[j]*X[i]*X[i])/(X[i]*X[j]*(X[j]-X[i]));
if(A > eps) continue;
for(k = 0; k < n; k++) if(zero(A*X[k]*X[k]+B*X[k]-Y[k])) g[i][j] += 1<<k;
}
}
memset(f, 63, sizeof(f));
f[0] = 0;
int mx = 1<<n;
for(i = 0; i < mx; i++){
for(j = 0; j < n; j++) down(f[i|(1<<j)], f[i]+1);
for(j = 0; j < n; j++){
for(k = 0; k < n; k++) down(f[i|g[j][k]], f[i]+1);
}
}
printf("%d\n", f[mx-1]);
}
return 0;
}
再过几天就是最后一次了吧.. 最后一个赛季怎么样都要加油啊..
不要犯低级错误..
不要自己卡自己
写好对拍
好好检查
用点心
嗯
标签:+= pop efi logs 错误 string ace a* sizeof
原文地址:http://www.cnblogs.com/darklove/p/7794877.html