Ultimate Weirdness of an Array
题意:给一个数列ai, f(i,j) 定义为除去i到j之间的数后最大gcd(ai, aj)的值, 求所有f(i,j)之和
#include <iostream> #include <string> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <vector> #include <map> #include <bitset> #include <queue> #include <set> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; #define LL long long #define ULL unsigned long long #define eps 1e-9 #define N (200000+ 10) #define M (10000000 + 10) #define pii pair<int,int> #define MP make_pair #define inf 0x3f3f3f3f #define lson ll, md, ls #define rson md + 1, rr, rs #define ls (i<<1) #define rs (i<<1|1) #define mod 9973 int a[N]; int l1[N], l2[N], r1[N], r2[N]; void mark(int j, int i) { if(!l1[j]) l1[j] = i; else if(!l2[j]) l2[j] = i; r2[j] = r1[j]; r1[j] = i; } int mx[N<<2], mi[N<<2]; LL b[N],s[N<<2]; int c[N<<2]; void update(int l, int r, int v, int ll, int rr, int i) { if(l > r) return ; if(mi[i] >= v) return ; if(ll == rr) { mx[i] = max(mx[i], v); mi[i] = mx[i]; s[i] = mx[i]; return ; } if(ll == l && r == rr && mx[i] <= v) { mx[i] = mi[i] = v; s[i] = (LL)v * (rr-ll+1); c[i] = v; return ; } if(c[i]) { int len = rr-ll+1; c[ls] = c[i], c[rs] = c[i]; mi[ls] = mx[ls] = c[i], mi[rs] = mx[rs] =c[i]; s[ls] = (LL)(len-len/2) * c[i], s[rs] = (LL)len/2 * c[i]; c[i] = 0; } int md = ll+rr>> 1; if(r <= md) update(l, r, v, lson); else if(l > md) update(l, r, v, rson); else update(l, md, v, lson), update(md+1, r, v, rson); mx[i] = max(mx[ls], mx[rs]); mi[i] = min(mi[ls], mi[rs]); s[i] = s[ls] + s[rs]; } int main() { //freopen("in.txt", "r", stdin); int n; scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); for(int i = 1; i <= n; ++i) { int y = (int)sqrt(a[i] *1.0); for(int j = 1; j <= y; ++j) { if(a[i] % j == 0) { mark(j, i); if(j * j != a[i]) mark(a[i]/j, i); } } } for(int i = 1; i <= n; ++i) update(i, i, i, 1, n, 1); int Max = 200005; for(int i = Max; i >= 1; --i) { if(l1[i] != r1[i]) { update(1, l1[i], r2[i], 1, n, 1); update(l1[i]+1, l2[i], r1[i], 1, n, 1); update(l2[i]+1, n, n+1, 1, n, 1); } b[i] = (LL)n*(n+1) - s[1]; } LL ans = 0; for(int i = 1; i < Max; ++i) ans += (b[i+1]-b[i]) * i; printf("%I64d\n", ans); }
题意:给一个有根树,m条路径u,v,费用为ci,v是u的祖先,选取一些路径覆盖树上所有边
#include <iostream> #include <string> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <vector> #include <map> #include <bitset> #include <queue> #include <set> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; #define LL long long #define ULL unsigned long long #define eps 1e-9 #define N (300000+ 10) #define M (1000000 + 10) #define pii pair<int,int> #define MP make_pair #define md (ll+rr>>1) #define lson ll, md, ls #define rson md + 1, rr, rs #define ls (i<<1) #define rs (i<<1|1) #define mod 9973 const LL inf = (LL) 1e15; int fst[N], vv[M], nxt[M], e; void init() { memset(fst, -1, sizeof fst); e = 0; } void add(int u, int v) { vv[e] =v, nxt[e] = fst[u], fst[u] = e++; } vector<int> st[N], ed[N]; int sid[N], tid[N], id[N], dc; void dfs(int u, int p) { sid[u] = dc+1; for(int i = 0; i < st[u].size(); ++i) id[st[u][i]] = ++dc; for(int i = fst[u]; ~i; i = nxt[i] ){ int v = vv[i]; if(v == p) continue; dfs(v, u); } tid[u] = dc; } struct node { int u, v, c; node() {} node(int u, int v, int c) : u(u), v(v), c(c) {}; }que[N]; int n, m; LL mi[N<<2], lazy[N<<2]; LL dp[N]; void build(int ll, int rr, int i) { if(ll > rr) return ; mi[i] = inf; if(ll == rr) return ; build(lson); build(rson); } void up(int i) { mi[i] = min(mi[ls], mi[rs]); mi[i] = min(mi[i], inf); } void down(int i) { if(lazy[i]) { mi[ls] = min(inf, mi[ls] + lazy[i]); mi[rs] = min(inf, mi[rs] + lazy[i]); lazy[ls] += lazy[i]; lazy[ls] = min(inf, lazy[ls]); lazy[rs] += lazy[i]; lazy[rs] = min(inf, lazy[rs]); lazy[i] = 0; } } LL query(int l, int r, int ll, int rr, int i) { if(l > r) return inf; if(l == ll && r == rr) { return mi[i]; } down(i); if(r <= md) return query(l, r, lson); else if(l > md) return query(l,r, rson); else return min(query(l, md, lson), query(md+1, r, rson)); } void update(int x, LL v, int ll, int rr, int i) { if(ll == rr) { mi[i] = v; return ; } down(i); if(x <= md) update(x, v, lson); else update(x, v, rson); up(i); } void update(int l, int r, LL v, int ll, int rr, int i) { if(l > r) return ; if(l == ll && r == rr) { mi[i] = min(inf, mi[i] + v); lazy[i] += v; lazy[i] = min(inf, lazy[i]); return ; } down(i); if(r <= md) update(l, r, v, lson); else if(l > md) update(l, r, v, rson); else update(l, md, v, lson), update(md+1, r, v, rson); up(i); } void f(int u, int p) { LL tot = 0; for(int i = fst[u]; ~i; i = nxt[i]) { int v = vv[i]; if(v == p) continue; f(v, u); tot += dp[v]; } if(u == 1) { dp[u] = tot; return ; } for(int i = 0; i < st[u].size(); ++i) update(id[st[u][i]],tot+ que[st[u][i]].c , 1, m, 1); for(int i = 0; i < ed[u].size(); ++i) update(id[ed[u][i]], inf, 1, m, 1); for(int i = fst[u]; ~i; i = nxt[i]) { int v = vv[i]; if(v == p) continue; update(sid[v], tid[v], tot-dp[v], 1, m, 1); } dp[u] = query(sid[u], tid[u], 1, m, 1); } int main() { //freopen("in.txt", "r", stdin); scanf("%d%d", &n, &m); int u, v; init(); for(int i = 1; i < n; ++i) { scanf("%d%d", &u, &v); add(u, v), add(v, u); } for(int i = 1; i <= m; ++i) { int w; scanf("%d%d%d",&u, &v, &w); que[i] = node(u, v, w); st[u].push_back(i); ed[v].push_back(i); } dfs(1, 0); //build(1, m, 1); f(1, 0); LL ans = dp[1]; if(ans >= inf || ans < 0) ans = -1; printf("%I64d\n", ans); }