CCPC-Wannafly Winter Camp Day5 (Div2, onsite)
A题 将一棵树画在平面上,使得没有边相交。
反正我WA了17次
犯的错误:
- 用vector存边的时候,点是无序的,需要排序预处理。
- 树存边的边是无向的。
#include <bits/stdc++.h>
#define LL long long
#define N 1010
#define M 2010
using namespace std;
int m,n;
vector<int> e[N];
struct node{
int x,y;
}c[N];
int maxy[N],sum=0;
void init(){
int u,v;
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
for(int i=1;i<=n;i++)
sort(e[i].begin(),e[i].end());
memset(maxy,0,sizeof maxy);
}
void dfs(int cur,int k,int Lastk){
if (cur>n+1) return;
c[k].x = cur;
c[k].y = ++maxy[cur];
for (int i=0;i<e[k].size();i++)
if (e[k][i]!=Lastk) dfs(cur+1,e[k][i],k);
}
int main(){
init();
dfs(1,1,0);
for (int i=1;i<=n;i++) printf("%d %d\n",c[i].x,c[i].y);
return 0;
}
C题 题意为每次,选择一个数ai,使其变成[ai/2],使剩余数之和最大。
显然每次取出最大数,用优先队列模拟操作即可。
Div1 丧心病狂数据量到10w数和50w操作,显然不能这样做。
dls的做法:
- 对于⼀一个数字,求出每步操作的贡献。(整除2)
- 答案就是区间最⼤大的k个数字,可以⽤用主席树解决。
- 但是直接⽤用主席树做可能会有空间问题。
- 我们把所有的数字分到2k到2(k+1)分别做。
- 时间复杂度O(n log ^2 n + q log n),空间O(n log n)
H题一开始看着像是点分治,然而…
• Div 2 : 可以把整个树建出来,对于⼀一条边,对答案的贡献 是两端size乘积的和
- Div1: 把所有树串串起来之后,某些边的两端的⼤大⼩小会变。 我们可以⽤用虚树/树链剖分解决。
J题 计算几何。上课效果检验题,判断线段相交。
•没有公共端点就是不不规范相交。
• 有就是判是不不是同⼀一个⽅方向,⽤用叉积+点积即可