Educational Round 47

最后拿了rank 9

F感觉自己想出来了很开心

=====================

A题题面真长

题意:

一个人在买东西

他会依次拿出面额为a1,a2...am的钱,尝试去买

如果一个东西的价格少于这个面额,则买下来(对方不找零钱),否则跳过这个物品

求买了多少武力

m<=1000,n<=1000

直接做

B题

给你一个012的字符串,你可以任意交换相邻的01,交换相邻的12,但不可以交换02

求最后可以得到的字典序最小的字符串

|S|<=100000

做法:

把所有的1都放在第一个2前面,如果没有2就放最后

C题

n个数,初始都是0

m次操作,每次选一个i,然后每个数加x+d*|i-j|

给你每次操作的x和d

你自己选择i

求平均值的最大值

|x|,|d|<=1000

n,m<=100000

做法:

x显然是直接在平均值上操作

d*|i-j|

如果d=0显然无所谓

d>0,那么我们在最边上,|i-j|的和最大,也即0+1+...+n

d<0,那么我们在最中间,如果有两个最中间随便选一个

D题

让你构造一个联通图

n个点,m个边,每条边必须连接两个互质的点

n,m<=100000

做法:

其实还是直接做

n2的直接暴力枚举i,j

如果gcd为1就连边,如果边用光就退出

注意特判m<n-1,直接输出-1

做法正确性:

看起来是n2的暴力,n是100000,过不去

但是当n>=10000的时候,我们可以发现枚举几十个m就超过100000了

所以复杂度实际上是对的

E题

从A到B一共有n公里,A在第0公里,B在第n公里

中间的每一公里都有可能有或者没有休息站(一共2n-1种可能性)

我们每次从一个休息站出发后,第一公里消耗体力为a1,第二公里为a2....第n公里为an

求在这2n-1种方案中,一共要消耗多少体力

n<=106,

1<=a1<=a2<=...<=an<=106

做法:

挺有趣的题

我们考虑,在什么情况下会贡献第i公里的消耗

我们发现,只有在一个休息站后连续i-1公里都没有休息站的情况下会,剩下的任意放

注意这个休息站可以是在0位置,所以要特殊处理一下

=======================

F题

n个点的树

对于每个点,我们有它的子树

设它在它的子树中第i层深度的节点数为ai,求最大值的下标

特别的,根节点深度为0

如果有多个,求最小的那一个

对于每个点都要求一遍

例如 

1-2-3/4这棵树中(1-2,2-3,2-4)

1的答案为2,因为3,4深度都为2

2的答案为1,因为在2的子树中,3,4的深度为1

3,4的答案为0,因为它自己就是最大值

=================================

n<=106

做法:

首先我用了树链剖分的办法把树给剖开,然后进行启发式合并

根据树链剖分中我们知道的,一个点到根最多只有log级别条重链 也就是最多只有log级的轻边

所以我们可以存储最多log级那么多个的数组(我怕MLE用的vector)

然后我们dfs一遍,对于每个点如果它在轻边上就新开一个vector,在整个子树访问完了以后合并到上一级的vector上(暴力合并),并且把这个vector给清空

总体复杂度O(n log n),不会证明

===============================

代码:

A

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int a[1005],b[1005];
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int n,m;
    scanf("%d%d",&n,&m);
    int i;
    for (i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    for (i=0;i<m;i++)
    {
        scanf("%d",&b[i]);
    }
    int now=0;
    for (i=0;i<n;i++)
    {
        if (b[now]>=a[i])
        {
            now++;
        }
    }
    printf("%d
",now);
    return 0;
}

B

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
char a[100005];
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    scanf("%s",a);
    int i;
    int cnt=0;
    for (i=0;a[i]!='';i++)
    {
        if (a[i]=='1') cnt++;
    }
    for (i=0;a[i]!='';i++)
    {
        if (a[i]=='2')
        {
            int j;
            for (j=0;j<cnt;j++)
            {
                printf("1");
            }
            cnt=0;
        }
        if (a[i]!='1')
        {
            printf("%c",a[i]);
        }
    }
    int j;
    for (j=0;j<cnt;j++)
    {
        printf("1");
    }
    printf("
");
    return 0;
}

C

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
long long val(int x)
{
    return (long long)x*(x+1)/2;
}
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int n,m;
    scanf("%d%d",&n,&m);
    int i;
    long long now_ans=0;
    for (i=0;i<m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        now_ans+=x*n;
        if (y<0)
        {
            now_ans+=(long long)(val(n/2)+val(n-n/2-1))*y;
        }
        else
        {
            now_ans+=(long long)val(n-1)*y;
        }
    }
    printf("%.21lf
",now_ans*1.0/n);
    return 0;
}

D

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
vector<pair<int,int> > ans;
int gcd(int x,int y)
{
    if (y==0) return x;
    return gcd(y,x%y);
}
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int n,m;
    scanf("%d%d",&n,&m);
    if (m<n-1)
    {
        puts("Impossible");
        return 0;
    }
    int i;
    for (i=1;i<=n;i++)
    {
        int j;
        for (j=i+1;j<=n;j++)
        {
            if (m==0) break;
            if (gcd(j,i)==1)
            {
                ans.push_back(make_pair(i,j));
                m--;
            }
        }
        if (m==0) break;
    }
    if (m!=0)
    {
        puts("Impossible");
    }
    else
    {
        puts("Possible");
        for (i=0;i<ans.size();i++)
        {
            printf("%d %d
",ans[i].first,ans[i].second);
        }
    }
    return 0;
}

E

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int modo=998244353;
int a[1000005];
int power2[1000005];
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int n;
    scanf("%d",&n);
    int i;
    for (i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    power2[0]=1;
    for (i=1;i<=n;i++)
    {
        power2[i]=power2[i-1]*2%modo;
    }
    int ans=0;
    for (i=1;i<=n;i++)
    {
        ans=(ans+(long long)power2[n-i]*a[i-1])%modo;
        if (i!=n)
        {
            ans=(ans+(long long)(n-i)*power2[n-i-1]%modo*a[i-1])%modo;
        }
    }
    printf("%d
",ans);
    return 0;
}

F

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int a[1000005];
int ans[1000005];
int fa[1000005];
struct edge
{
    int y;
    edge * next;
};
edge * new_edge()
{
    static edge a[4000005];
    static int top=0;
    return &a[top++];
}
const int maxn=1000005;
edge * li[maxn];
void inserts(int x,int y)
{
    edge * t=new_edge();
    t->y=y;
    t->next=li[x];
    li[x]=t;
}
void insert_edge(int x,int y)
{
    inserts(x,y);
    inserts(y,x);
}
int size[maxn];
int depth[maxn];
int preffered[maxn];
void dfs1(int x)
{
    edge * t;
    size[x]=1;
    for (t=li[x];t!=0;t=t->next)
    {
        if (t->y==fa[x]) continue;
        fa[t->y]=x;
        depth[t->y]=depth[x]+1;
        dfs1(t->y);
        size[x]+=size[t->y];
    }
    int now_max=-1;
    for (t=li[x];t!=0;t=t->next)
    {
        if (t->y==fa[x]) continue;
        if ((now_max==-1)||(size[t->y]>size[now_max]))
        {
            now_max=t->y;
        }
    }
    preffered[x]=now_max;
}
vector<int> anss[405];
int add_depth[405];
int the_max[405];
bool cmp(int a,int b,int c,int d)
{
    if (a>c) return true;
    if (a<c) return false;
    return b<d;
}
void dfs2(int x,bool is_preffered)
{
    static int cnt=0;
    if (!is_preffered)
    {
        cnt++;
        anss[cnt].resize(0);
        anss[cnt].push_back(1);
        add_depth[cnt]=depth[x];
        the_max[cnt]=0;
    }
    else
    {
        int k=depth[x]-add_depth[cnt];
        if ((int)anss[cnt].size()<=k)
        {
            anss[cnt].resize(k+1,0);
        }
        anss[cnt][k]++;
        if (cmp(anss[cnt][k],k,anss[cnt][the_max[cnt]],the_max[cnt]))
        {
            the_max[cnt]=k;
        }
    }
    if (preffered[x]!=-1)
    {
        dfs2(preffered[x],true);
    }
    edge * t;
    for (t=li[x];t!=0;t=t->next)
    {
        if (t->y==preffered[x]) continue;
        if (t->y==fa[x]) continue;
        dfs2(t->y,false);
    }
    ans[x]=max(0,the_max[cnt]+add_depth[cnt]-depth[x]);
    if (!is_preffered)
    {
        int k=depth[x]-add_depth[cnt-1]+anss[cnt].size();
        int delta=depth[x]-add_depth[cnt-1];
        if ((int)anss[cnt-1].size()<k)
        {
            anss[cnt-1].resize(k,0);
        }
        int i;
        for (i=0;i<(int)anss[cnt].size();i++)
        {
            anss[cnt-1][i+delta]+=anss[cnt][i];
            if (cmp(anss[cnt-1][i+delta],i+delta,anss[cnt-1][the_max[cnt-1]],the_max[cnt-1]))
            {
                the_max[cnt-1]=i+delta;
            }
        }
        anss[cnt].erase(anss[cnt].begin(),anss[cnt].end());
        cnt--;
    }
}
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int n;
    scanf("%d",&n);
    int i;
    for (i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        x--;
        y--;
        insert_edge(x,y);
    }
    fa[0]=-1;
    dfs1(0);
    dfs2(0,true);
    for (i=0;i<n;i++)
    {
        printf("%d
",ans[i]);
    }
    return 0;
}

======================

P.S.

G

我不会做

求大佬教教我

原文地址:https://www.cnblogs.com/absi2011/p/9315307.html