汇思学 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;
}
考场代码,纪念一下 qwq

正解:

  

#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;
}
std

 

期望得分: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;
}
std

 

 期望得分: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;
}
std

 

posted @ 2018-10-02 20:14  落云小师妹  阅读(235)  评论(0编辑  收藏  举报