汇思学 18国庆 考一
期望得分:40?实际得分:10 嘤嘤嘤
考场思路:预处理前缀和,n2从大到小枚举区间长度和左端点,可以推出右端点
将枚举的区间和存到数组里,排序后输出
#include <algorithm> #include <cstring> #include <cstdio> #include <queue> using namespace std; typedef long long LL; const int M = 100005; bool flag = 0; int n, m, tot; int a[M]; LL sum[M], ans[M]; bool cmp(int x, int y) { return x > y; } int main() { freopen("ksum.in","r",stdin); freopen("ksum.out","w",stdout); scanf("%d%d", &n, &m); if (n <= 1000) flag = 1; for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); sum[i] = a[i] + sum[i - 1]; } ans[++tot] = sum[n]; if (!flag) for (int i = n - 1; i >= 1; --i) { for (int j = 0; j + i <= n; ++j) { int k = j + i; ans[++tot] = sum[k] - sum[j]; } if (tot > m) break; } else for (int i = n - 1; i >= 1; --i) for (int j = 0; j + i <= n; ++j) { int k = j + i; ans[++tot] = sum[k] - sum[j]; } sort(ans + 1, ans + tot + 1, cmp); for (int i = 1; i <= m; ++i) printf("%d ", ans[i]); fclose(stdin); fclose(stdout); return 0; }
正解:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<set> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define maxn 100005 #define fi first #define se second #define mp(a,b) make_pair(a,b) #define ll long long #define pr pair< ll,pair<int,int> > using namespace std; int n,k; int a[maxn]; ll sum; set< pr > s; int read(){ int ret=0,ff=1; char c=getchar(); while (c<'0' || c>'9') { c=getchar(); } while (c>='0' && c<='9') { ret=ret*10+c-'0'; c=getchar(); } return ret; } int main(){ freopen("ksum.in","r",stdin); freopen("ksum.out","w",stdout); n=read(); k=read(); fo(i,1,n){ a[i]=read(); sum+=a[i]; } s.insert(mp(sum,mp(1,n))); while (k--) { pr now=*s.rbegin(); printf("%lld ",now.fi); s.erase(now); int l=now.se.fi; int r=now.se.se; if (l!=r) { s.insert(mp(now.fi-a[l],mp(l+1,r))); s.insert(mp(now.fi-a[r],mp(l,r-1))); } } return 0; }
期望得分:10?30?实际得分:10
m = n - 1 的 10 分到手了,本来还想写写另外20%来着
然后。。就没有然后了
#include <algorithm> #include <cstring> #include <cstdio> #include <queue> #include <map> using namespace std; const int M = 100005; int n, m, k, tot; int cu[M], ru[M]; int to[M*2], net[M*2], head[M]; int fa[M]; void add(int u, int v) { to[++tot] = v; net[tot] = head[u]; head[u] = tot; to[++tot] = u; net[tot] = head[v]; head[v] = tot; } queue<int> q; void dfs(int now) { q.push(now); while (!q.empty()) { int x = q.front(); q.pop(); for (int i = head[x]; i; i = net[i]) { fa[i] = x; q.push(i); } } } queue<int> Q; map<int, int> ma; void dfsl(int now) { Q.push(now); while (Q.empty()) { int x = Q.front(); Q.pop(); for (int i = head[x]; i; i = net[i]) { if (ma[i] == 0) ++ma[i]; else { tot = 1; break; } ru[++k] = i; Q.push(i); } if (tot) break; } printf("%d\n", k); sort(ru+1, ru+k+1); for (int i = 1; i <= k; ++i) printf("%d ", ru[i]); } int main() { freopen("tree.in","r",stdin); freopen("tree.out","w",stdout); bool flag = 0, flag2 = 0; scanf("%d%d", &n, &m); if (n - 1 == m) flag = 1; if (n == m) flag2 = 1; for (int i = 1; i <= m; ++i) { int u, v; scanf("%d%d", &u, &v); add(u, v); ++cu[u], ++cu[v]; } if (flag) { for (int i = 1; i <= n; ++i) if (cu[i] == 1) ru[++k] = i; printf("%d\n", k); for (int i = 1; i <= k; ++i) printf("%d ", ru[i]); return 0; } if (flag2) { int tmp = 0, t; for (int i = 1; i <= n; ++i) { if (cu[i] == 1) dfs(i), ++tmp; if (cu[i] == 3) t = i, ++tmp; if (tmp == 2) break; } dfsl(t); return 0; } fclose(stdin); fclose(stdout); return 0; }
正解:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define maxn 100005 using namespace std; int low[maxn],dfn[maxn],tim; int head[maxn],t[maxn * 2],next[maxn * 2],sum; int d[maxn]; bool bz[maxn],vis[maxn]; int n,m; int ans[maxn]; void insert(int x,int y){ t[++sum]=y; next[sum]=head[x]; head[x]=sum; } void dfs(int x,int father) { low[x]=dfn[x]=++tim; vis[x]=1; int tot=0; for(int tmp=head[x];tmp;tmp=next[tmp]) { if (t[tmp]==father) continue; if (vis[t[tmp]]) { low[x]=min(low[x],low[t[tmp]]); } else { tot++; dfs(t[tmp],x); low[x]=min(low[x],low[t[tmp]]); if (father!=0 && low[t[tmp]]>=dfn[x]) bz[x]=1; } } if (father==0 && tot>1) bz[x]=1; } int main(){ freopen("tree.in","r",stdin); freopen("tree.out","w",stdout); scanf("%d%d",&n,&m); fo(i,1,m) { int x,y; scanf("%d%d",&x,&y); insert(x,y); insert(y,x); d[x]++; d[y]++; } dfs(1,0); fo(i,1,n) { if(d[i]==m-n+2 && !bz[i]) ans[++ans[0]]=i; } printf("%d\n",ans[0]); fo(i,1,ans[0]) printf("%d ",ans[i]); return 0; }
期望得分:0?实际。。。也是0
码了个暴力,没想到连样例都过不了。。。
开始调。。。
好不容易过样例了,自己造了个数据,过不了。。。
继续调。。。调完后样例又过不了了。。。
然后又改回去,放弃这道题了 qwq
#include <algorithm> #include <cstring> #include <cstdio> using namespace std; const int M = 200005; int n, k, t, maxn; int a[M], f; int q[M]; long long ans; long long mul(int a, int b) { long long res = 0; while (b) { if (b & 1) res += a; a += a; b >>= 1; } return res; } void work(int now) { for (int i = 0; i < now; ++i) { --q[a[i]]; for (int j = n; j >= now; --j) { for (int t = 1; t <= maxn; ++t) { // printf("%d ", q[t]); if (q[t] == 0) { ans += t; // printf("%d\n", t); break; } if (t == maxn) ans += maxn + 1; } --q[a[j]]; } } // printf("\n"); } int main() { freopen("mex.in","r",stdin); freopen("mex.out","w",stdout); scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); if (a[i] == 0) f = i, ++k; ++q[a[i]]; maxn = max(maxn, a[i]); } if (k == 0) return printf("0\n"), 0; work(f); // printf("%d\n", ans); printf("%lld\n", mul(ans, k)); fclose(stdin); fclose(stdout); return 0; } /* 7 0 1 4 2 0 3 2 */
正解:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define maxn 200005 #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) #define oo 1e9 using namespace std; bool bz[maxn]; int a[maxn],n; int p[maxn],last[maxn],Next[maxn]; ll ans; struct note{ ll mx,sum; ll tag; }t[maxn * 4]; void build(int v,int l,int r){ if (l==r) { t[v].mx=t[v].sum=p[l]; t[v].tag=oo; return; } int mid=(l+r) >> 1; build(v << 1,l,mid); build(v << 1 | 1,mid+1,r); t[v].sum=t[v << 1].sum+t[v << 1 | 1].sum; t[v].mx=max(t[v << 1].mx,t[v << 1 | 1].mx); t[v].tag=oo; } void update(int v,int l,int r){ if (t[v].tag==oo) return; int mid=(l+r) >> 1; t[v << 1].mx=t[v << 1 | 1].mx=t[v].tag; t[v << 1].sum=t[v].tag*(mid-l+1); t[v << 1 | 1].sum=t[v].tag*(r-mid); t[v << 1].tag=t[v << 1 | 1].tag=t[v].tag; t[v].tag=oo; } void change(int v,int l,int r,int x,int y,int z){ if (l!=r) update(v,l,r); if (l==x && r==y) { t[v].tag=z; t[v].mx=z; t[v].sum=z*1ll*(r-l+1); return; } int mid=(l+r) >> 1; if (y<=mid) change(v << 1,l,mid,x,y,z); else if (x>mid) change(v << 1 | 1,mid+1,r,x,y,z); else change(v << 1,l,mid,x,mid,z),change(v << 1 | 1,mid+1,r,mid+1,y,z); t[v].sum=t[v << 1].sum+t[v << 1 | 1].sum; t[v].mx=max(t[v << 1].mx,t[v << 1 | 1].mx); } int getl(int v,int l,int r,int x){ if (l==r) return l; if (l!=r) update(v,l,r); int mid=(l+r) >> 1; if (t[v << 1].mx>x) return getl(v << 1,l,mid,x); else return getl(v << 1 | 1,mid+1,r,x); } int main(){ freopen("mex.in","r",stdin); freopen("mex.out","w",stdout); scanf("%d",&n); fo(i,1,n) { scanf("%d",&a[i]); if (a[i]>n) a[i]=n+1; } int now=0; fo(i,1,n) { bz[a[i]]=1; while (bz[now]) now++; p[i]=now; } fd(i,n,1) { if (last[a[i]]) Next[i]=last[a[i]]; else Next[i]=n+1; last[a[i]]=i; } build(1,1,n); fo(i,1,n) { ans+=t[1].sum; if (t[1].mx>a[i]) { int l=getl(1,1,n,a[i]); int r=Next[i]; if (l<=r-1) change(1,1,n,l,r-1,a[i]); } change(1,1,n,i,i,0); } printf("%lld",ans); return 0; }