最后拿了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\n",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]!='\0';i++)
{
if (a[i]=='1') cnt++;
}
for (i=0;a[i]!='\0';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("\n");
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\n",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\n",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\n",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\n",ans[i]);
}
return 0;
}
======================
P.S.
G
我不会做
求大佬教教我