平时二十五测改写为:日常进行25次测试通常是什么?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1319个文字,预计阅读时间需要6分钟。
今天翻盘了,没犯上次两次的愚蠢错误;解题:其或(N)(N≥T)不检查,不是严谨的,而且回e6面的约数很少,从重心跑很快。
今天翻盘了,没有上两次的傻逼错误;题解:其实O(N)check不会T,不是严格的,而且1e6里面的约数很少,从重心跑很快;#incl今天翻盘了,没有上两次的傻逼错误;
题解:
其实O(N)check不会T,不是严格的,而且1e6里面的约数很少,从重心跑很快;
#includeusing namespace std;#define ex(i, u) for(int i = h[u]; i; i = G[i].nxt)const int M = 1e6 + 5;int h[M], fg ,tot, siz[M], f[M], tmp[M], n, root, vis[M];struct edge{int v, nxt;}G[M<<1];void add(int u, int v){G[++tot].v = v, G[tot].nxt = h[u], h[u] = tot;}void getroot(int u, int fa){ siz[u] = 1; ex(i, u){ int v = G[i].v; if(v == fa) continue; getroot(v, u); siz[u] += siz[v]; f[u] = max(f[u], siz[v]); } f[u] = max(f[u], n - siz[u]); if(f[u]这道题还有一个巧妙的剪枝,不用O(N)枚举起点,对于一个点,他在传递过程的位置是1——最后,我们把1当起点,做一遍不行,就把他当第二个,当他作为最后一个后就可以停了,实测跑得飞快(这样不倍增都有60分)
#includeusing namespace std;const int M = 1e5 + 5;int n, a[M], m, s[M];bool check(int k){ int up = n, tot = 0, lst = 0; while(1){ int cnt = 1; for(int i = 1; i <= up; i++){ if(tot + a[i] <= k) tot += a[i]; else tot = a[i], cnt++; } if(cnt k) return 0; } }int read(){ int x=0,f=1;char c=getchar(); while(c'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'c=getchar();} return x*f;}bool check2(int k){ int up = n, tot = 0, lst = 0; while(1){ int cnt = 1; for(int i = 1; i <= up; ){ int lf = i, rg = up, rec = -1; while(lf > 1; if(s[mid] - s[i - 1] + tot <= k) rec = mid, lf = mid + 1; else rg = mid - 1; } tot = 0; i = rec + 1; if(i == up + 1)break; cnt++; } if(cnt k) return 0; }}int main(){ freopen("dinner.in","r",stdin); freopen("dinner.out","w",stdout); n = read(); m = read(); int ans = -1, Mx = 0, sum = 0; for(int i = 1; i <= n; i ++) { a[i] = read(), sum += a[i], Mx = max(Mx, a[i]); s[i] = s[i - 1] + a[i]; } int lf = Mx, rg = sum; if(n <= 5000){ while(lf > 1; if(check(mid)) ans = mid, rg = mid - 1; else lf = mid + 1; } } else { while(lf > 1; if(check2(mid)) ans = mid, rg = mid - 1; else lf = mid + 1; } } printf("%d\n", ans); } View Code一句话:最短路+缩边
本文共计1319个文字,预计阅读时间需要6分钟。
今天翻盘了,没犯上次两次的愚蠢错误;解题:其或(N)(N≥T)不检查,不是严谨的,而且回e6面的约数很少,从重心跑很快。
今天翻盘了,没有上两次的傻逼错误;题解:其实O(N)check不会T,不是严格的,而且1e6里面的约数很少,从重心跑很快;#incl今天翻盘了,没有上两次的傻逼错误;
题解:
其实O(N)check不会T,不是严格的,而且1e6里面的约数很少,从重心跑很快;
#includeusing namespace std;#define ex(i, u) for(int i = h[u]; i; i = G[i].nxt)const int M = 1e6 + 5;int h[M], fg ,tot, siz[M], f[M], tmp[M], n, root, vis[M];struct edge{int v, nxt;}G[M<<1];void add(int u, int v){G[++tot].v = v, G[tot].nxt = h[u], h[u] = tot;}void getroot(int u, int fa){ siz[u] = 1; ex(i, u){ int v = G[i].v; if(v == fa) continue; getroot(v, u); siz[u] += siz[v]; f[u] = max(f[u], siz[v]); } f[u] = max(f[u], n - siz[u]); if(f[u]这道题还有一个巧妙的剪枝,不用O(N)枚举起点,对于一个点,他在传递过程的位置是1——最后,我们把1当起点,做一遍不行,就把他当第二个,当他作为最后一个后就可以停了,实测跑得飞快(这样不倍增都有60分)
#includeusing namespace std;const int M = 1e5 + 5;int n, a[M], m, s[M];bool check(int k){ int up = n, tot = 0, lst = 0; while(1){ int cnt = 1; for(int i = 1; i <= up; i++){ if(tot + a[i] <= k) tot += a[i]; else tot = a[i], cnt++; } if(cnt k) return 0; } }int read(){ int x=0,f=1;char c=getchar(); while(c'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'c=getchar();} return x*f;}bool check2(int k){ int up = n, tot = 0, lst = 0; while(1){ int cnt = 1; for(int i = 1; i <= up; ){ int lf = i, rg = up, rec = -1; while(lf > 1; if(s[mid] - s[i - 1] + tot <= k) rec = mid, lf = mid + 1; else rg = mid - 1; } tot = 0; i = rec + 1; if(i == up + 1)break; cnt++; } if(cnt k) return 0; }}int main(){ freopen("dinner.in","r",stdin); freopen("dinner.out","w",stdout); n = read(); m = read(); int ans = -1, Mx = 0, sum = 0; for(int i = 1; i <= n; i ++) { a[i] = read(), sum += a[i], Mx = max(Mx, a[i]); s[i] = s[i - 1] + a[i]; } int lf = Mx, rg = sum; if(n <= 5000){ while(lf > 1; if(check(mid)) ans = mid, rg = mid - 1; else lf = mid + 1; } } else { while(lf > 1; if(check2(mid)) ans = mid, rg = mid - 1; else lf = mid + 1; } } printf("%d\n", ans); } View Code一句话:最短路+缩边

