湘潭邀请赛 2017 题解
E :Partial Sum
每次取任意两个不同的前缀,取过之后不能再取,最多取M次
将前缀和排序,优先取最大,最小就行了
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; const long long INF = 1e18+1LL; const double Pi = acos(-1.0); const int N = 5e5+10, M = 1e3+20, mod = 1e9+7,inf = 2e9; int n,m,c,sum[N],a[N],b[N]; int main() { while(scanf("%d%d%d",&n,&m,&c)!=EOF) { sum[0] = 0; int cnt =0; b[++cnt] = 0; for(int i = 1; i <= n; ++i) { scanf("%d",&a[i]); sum[i] = sum[i-1] + a[i]; b[++cnt] = sum[i]; } sort(b+1,b+cnt+1); int head = 1, tail = cnt; LL ans = 0; for(int i = 1; i <= m; ++i) { int f = b[head++]; int s = b[tail--]; if(abs(s-f)-c >= 0) { ans += abs(s-f)-c; } else break; } printf("%lld ",ans); } return 0; }
F:Longest Common Subsequence
将a数组离散化,枚举三元素,n^3
求LCS,花费n*3,现在总体复杂度是n^4的
求LCS这步可以 优化,我们预处理吃nex[i][c],当前i位置后面第一个c在哪里
就可以在2^3下O(1)求出LCS了
有个坑的地方就是 a[i]可能会大于m,wa了很久
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; const long long INF = 1e18+1LL; const double Pi = acos(-1.0); const int N = 2e2+10, M = 1e3+20, mod = 1e9+7,inf = 2e9; LL n,m,a[N],c,b[N],nex[N][N]; LL v[N]; LL f[N]; LL query(LL x) { return lower_bound(b+1,b+c+1,x) - b; } int main() { while(scanf("%lld%lld",&n,&m)!=EOF) { for(int i = 1; i <= n; ++i) scanf("%lld",&a[i]),b[i] = a[i]; sort(b+1,b+n+1); c = unique(b+1,b+n+1) - b - 1; for(int i = c; i >= 1; --i) { if(b[i] > m) c--; else break; } for(int i = 0; i <= 5; ++i) f[i] = 0; for(int i = 1; i <= n; ++i) a[i] = query(a[i]); memset(nex,0,sizeof(nex)); memset(v,0,sizeof(v)); for(int i = 0; i <= n; ++i) { for(int j = 1; j <= c; ++j) { for(int k = i+1; k <= n; ++k) { if(a[k] == j) { nex[i][j] = k; break; } } } } for(int i = 1; i <= c; ++i) v[i] = 1; v[c+1] = m - c; for(int i = 1; i <= c+1; ++i) { for(int j = 1; j <= c+1; ++j) { for(int k = 1; k <= c+1; ++k) { int fi = 0, se = 0, th = 0; for(int C = 1; C < 8; ++C) { int now = 0; if(C&(4)) { if(!nex[now][i]) {continue;} else now = nex[now][i]; } if(C&(2)) { if(!nex[now][j]) {continue;} else now = nex[now][j]; } if(C&(1)) { if(!nex[now][k]) {continue;} else now = nex[now][k]; } if(C == 7) fi = 1; else if(C == 6 || C == 5 || C == 3) se = 1; else if(C)th = 1; } if(fi){ f[3] += v[i]*v[j]*v[k]; } else if(se) { f[2] += v[i]*v[j]*v[k]; } else if(th) { f[1] += v[i]*v[j]*v[k]; } else { f[0] += v[i]*v[j]*v[k]; } } } } for(int i = 0; i < 3; ++i) cout<<f[i]<<" "; cout<<f[3]<<endl; } return 0; }