最后拿了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
我不会做
求大佬教教我