2018CCPC吉林赛区(重现赛)- 感谢北华大学

A

基础数论。

#include<bits/stdc++.h>
using namespace std; typedef long long LL; int main() {
int T,cc = 0;
scanf("%d",&T);
while(T --) {
int n;
scanf("%d",&n);
int ans = 0;
for(int i = 1,r;i <= n;i = r + 1) {
r = n / (n / i);
ans += (r-i+1ll) * (n / i) & 1;
}
if(ans&1) printf("Case %d: odd\n",++ cc);
else printf("Case %d: even\n",++ cc);
}
}

B

基础模拟。

#include<bits/stdc++.h>
using namespace std; typedef long long LL; int main() {
int T,cc = 0;
scanf("%d",&T);
map<string,int> mp;
mp["Beijing"] = 8;
mp["Washington"] = -5;
mp["London"] = 0;
mp["Moscow"] = 3;
while(T --) {
int h,m;
string s,name1,name2;
scanf("%d:%d",&h,&m);
cin >> s >> name1 >> name2;
h %= 12;
if(s == "PM") h += 12;
int delta = mp[name2] - mp[name1];
h += delta;
//cout << h << endl;
string rq;
if(h >= 24) rq = "Tomorrow";
else if(h < 0) rq = "Yesterday";
else rq = "Today";
h += 24; h %= 24;
string ans;
if(h <= 11) ans = "AM";
else ans = "PM",h -= 12;
if(h == 0) h = 12;
printf("Case %d: %s %d:%02d %s\n",++ cc,rq.c_str(),h,m,ans.c_str());
}
}

C

基础贪心。也可以写并查集。

#include<bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<int,int> pii;
const int SZ = 2e5 + 10; int bel[SZ],tot,sum,mark[SZ];
vector<int> g[SZ]; void dfs(int u,int c) {
bel[u] = c;
for(int v : g[u]) {
dfs(v,c);
}
} int main() {
int T,cc = 0;
scanf("%d",&T);
while(T --) {
int n;
scanf("%d",&n);
for(int i = 1;i <= tot;i ++) {
bel[i] = 0;
mark[i] = 0;
g[i].clear();
}
tot = n,sum = 0; priority_queue<pii> q;
for(int i = 1;i <= n;i ++) {
int x;
scanf("%d",&x);
q.push(make_pair(x,i));
}
while(q.size()) {
pii p = q.top(); q.pop();
if(p.first <= 1) { mark[p.second] = 1; sum ++; continue; }
if(q.size()) {
pii p2 = q.top(); q.pop();
if(p2.first == p.first) {
pii ans = make_pair(p.first-1,++ tot);
//printf("%d -> %d\n",tot,p.second);
// printf("%d -> %d\n",tot,p2.second);
g[tot].push_back(p.second);
g[tot].push_back(p2.second);
q.push(ans);
}
else q.push(p2);
}
}
if(sum < 2) {
printf("Case %d: NO\n",++ cc);
}
else {
printf("Case %d: YES\n",++ cc);
int t = 0;
for(int i = 1;i <= tot;i ++) {
if(mark[i]) {
dfs(i,t);
if(t==0) t++;
}
}
for(int i = 1;i <= n;i ++) printf("%d",bel[i]); puts("");
}
}
}

D

基础概率DP。由于会加1.5%所以状态要乘2。

#include<bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<int,int> pii;
const int SZ = 2e5 + 10; double f[333]; int main() {
int T,cc = 0;
scanf("%d",&T);
while(T --) {
int pp;
scanf("%d",&pp);
double p = 1.0*pp/100;
f[200] = 1/p;
for(int i = 199;i >= 4;i --) {
int nx1 = min(200,i+4);
int nx2 = min(200,i+3);
f[i] = p * (i/200.0+(1-i/200.0)*(f[nx1]+1))
+ (1-p) * (f[nx2] + 1);
}
printf("Case %d: %.10f\n",++ cc,f[4]);
}
}

E

推公式数学题。解方程。直接套求根公式比魔改求根公式的精度要高(?)

#include<bits/stdc++.h>
using namespace std; typedef long long LL;
const int MAXN=1e3+10;
const int mod=1e9+7;
const double eps=1e-7; int sgn(double a){
if (fabs(a)<eps) return 0;
if (a>0) return 1;
return -1;
} int main(){
int T,cas=0; scanf("%d",&T);
while(T--){
double r,h;
scanf("%lf%lf",&r,&h);
double ppx,ppy,ppz,ddx,ddy,ddz;
scanf("%lf%lf%lf",&ppx,&ppy,&ppz);
scanf("%lf%lf%lf",&ddx,&ddy,&ddz);
long double px=ppx,py=ppy,pz=ppz,dx=ddx,dy=ddy,dz=ddz;
long double ox=px,oy=py,oz=pz;
long double k = r*r/h/h;
long double a = dx * dx + dy * dy - k * dz * dz;
long double b = 2 * (dx * ox + dy * oy - k * dz * (oz - h));
long double c = ox * ox + oy * oy - k * (oz - h) * (oz - h);
long double discrim = b * b - 4 * a * c;
long double rootDiscrim = sqrt(discrim);
/*long double q;
if (b < 0) q = (-b + rootDiscrim)/2;
else q = (-b - rootDiscrim)/2;
long double t0 = q / a;
long double t1 = c / q;
long double ans=min(t0,t1);
if(ans < 1e-8) ans = 0;*/
long double ans = (-b-rootDiscrim)/2/a;
printf("Case %d: %.10f\n",++cas,(double)ans);
}
return 0;
}

F

因为左端点递增,所以 i 包含 k 那么 j 一定包含 k,所以 j 取 i-1 最优,每个点的答案就是 x-2。

#include<bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<int,int> pii;
const int SZ = 2e5 + 10;
const int mod = 1e9+7; LL read() {
LL n = 0;
char a = getchar();
bool flag = 0;
while(a > '9' || a < '0') { if(a=='-') flag = 1; a = getchar(); }
while(a <= '9' && a >= '0') { n=n*10+a-'0'; a = getchar(); }
if(flag) n=-n;
return n;
} int main() {
int T = read(),cc = 0;
while(T --) {
int n = read(),ans = 0;
for(int i = 1;i <= n;i ++) {
int x = read();
x = max(x-2,0);
ans ^= x;
}
printf("Case %d: %d\n",++ cc,ans);
}
}

G

题意:给 \(10^4\) 个一欧姆的电阻。定义一个元件:

  1. 一个一欧姆电阻是一个元件
  2. 两个元件并联是一个元件
  3. 两个元件串联是一个元件

构造一个元件,使得其电阻阻值与 \(r\) 的绝对值之差小于 \(10^{-7}\)

key:随机,乱搞

有连分数做法,不过不太会……

众所周知 n 个 a 欧姆的电阻并联的电阻是 a/n。想要得到一个尽量小的电阻那么一定是若干个一欧姆电阻并联。

考虑把 r 拆分成若干个 1/ki,这其实是埃及分数。我们的目标是使得 \(\sum k_i \le 10^4\) 。

考虑加入一个 1/ki,那么能算出 ki 的下界。每次选下界的贪心是不优的,而我们只需要找到一个较优解。

实际上只需要给下界加一个随机数调整,跑若干遍直到满足条件即可。实测大概跑个几遍就有了,随机了 \(10^5\) 组都能出解。

输出比较坑

#include<bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<int,int> pii;
const int SZ = 2e5 + 10;
const int mod = 1e9+7; LL read() {
LL n = 0;
char a = getchar();
bool flag = 0;
while(a > '9' || a < '0') { if(a=='-') flag = 1; a = getchar(); }
while(a <= '9' && a >= '0') { n=n*10+a-'0'; a = getchar(); }
if(flag) n=-n;
return n;
} mt19937 rd(2333); LL randlr(LL l,LL r) {
return rd()%(r-l+1)+l;
} vector<int> a; int work(double r) {
a.clear();
double now = 0;
int sum = 0;
while(fabs(now-r) > 1e-9) {
int k = 1/(r-now); if((r-now)*k<1) k++;
k += randlr(0,5);
now += 1.0/k;
sum += k;
a.push_back(k);
// printf("%.10f %d\n",now,k);
}
// puts("finish");
return sum;
} int main() {
int T = read(),cc = 0;
while(T --) {
// double r = randlr(1e7,9e7)/1e7;
double r;
scanf("%lf",&r);
printf("Case %d:\n",++ cc);
for(int i = 1;;i ++){
int sum = work(r);
if(sum <= 1e4) {
int m = sum - 1;
printf("%d %d\n",sum,m);
int t = sum-1,lst = 0;
// for(int x : a) cout << x << " "; puts("");
vector<int> b;
for(int x : a) {
printf("1 %d %d\n",lst,lst+1);
lst+=2; t ++; x --;
while(x -- > 1) printf("1 %d %d\n",lst,t),lst++,t++;
b.push_back(t);
}
int x = a.size();
if(x>1) {
printf("0 %d %d\n",b[0],b[1]); t++;
for(int j = 2;j < b.size();j ++)
printf("0 %d %d\n",b[j],t),t++;
}
break;
}
}
}
}

H

基础线段树。

#include<bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<int,int> pii;
const int SZ = 2e5 + 10;
const int mod = 1e9+7; LL read() {
LL n = 0;
char a = getchar();
bool flag = 0;
while(a > '9' || a < '0') { if(a=='-') flag = 1; a = getchar(); }
while(a <= '9' && a >= '0') { n=n*10+a-'0'; a = getchar(); }
if(flag) n=-n;
return n;
} int mi[SZ]; struct seg {
int l,r;
int sum,misum;
int x,rx,len;
}tree[SZ*4]; void update(int p) {
tree[p].sum = (tree[p<<1].sum+tree[p<<1|1].sum) % mod;
tree[p].misum = (tree[p<<1].misum+tree[p<<1|1].misum) % mod;
} void build(int p,int l,int r) {
tree[p].l = l;
tree[p].r = r;
tree[p].sum = 0;
tree[p].misum = 0;
tree[p].x = 0;
tree[p].rx = 0;
tree[p].len = 0;
if(l == r) {
tree[p].misum = 1;
return ;
}
int mid = l + r >> 1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
update(p);
} void pushc(int p,int x,int rx,int len) {
tree[p].sum = (1ll*mi[len]*tree[p].sum%mod+1ll*x*(tree[p].r-tree[p].l+1)%mod
+ 1ll*rx*tree[p].misum%mod*mi[len]%mod) % mod;
tree[p].misum = 1ll*mi[len*2]*tree[p].misum % mod;
tree[p].x = (1ll*tree[p].x*mi[len]%mod + x) % mod;
tree[p].rx = (tree[p].rx + 1ll*rx*mi[tree[p].len] % mod) % mod;
tree[p].len += len;
} void pushdown(int p) {
if(tree[p].len) {
pushc(p<<1,tree[p].x,tree[p].rx,tree[p].len);
pushc(p<<1|1,tree[p].x,tree[p].rx,tree[p].len);
tree[p].len = 0;
tree[p].x = 0;
tree[p].rx = 0;
}
} void change(int p,int l,int r,int d) {
if(l<=tree[p].l&&tree[p].r<=r) {
pushc(p,d,d,1);
return ;
}
pushdown(p);
int mid = tree[p].l + tree[p].r >> 1;
if(l <= mid) change(p<<1,l,r,d);
if(mid < r) change(p<<1|1,l,r,d);
update(p);
} int ask(int p,int l,int r) {
if(l<=tree[p].l&&tree[p].r<=r) {
return tree[p].sum;
}
pushdown(p);
int mid = tree[p].l + tree[p].r >> 1,ans = 0;
if(l <= mid) (ans += ask(p<<1,l,r)) %= mod;
if(mid < r) (ans += ask(p<<1|1,l,r)) %= mod;
return ans;
} int main() {
mi[0] = 1;
for(int i = 1;i <= 2e5;i ++) mi[i]=mi[i-1]*10ll%mod;
int T = read(),cc = 0;
while(T--) {
int n = read(),m = read();
build(1,1,n);
printf("Case %d:\n",++ cc);
while(m --) {
char s[6];
scanf("%s",s);
int l = read(),r = read();
if(s[0] == 'w') {
int d = read();
change(1,l,r,d);
}
else {
printf("%d\n",ask(1,l,r));
}
}
}
}

I

要么全打完,那么肯定用刚好打过这个怪的打他。要么不打完,那么防御怪都不打,剩下的田忌赛马。

J

题意:给 n 个球, m 个颜色,给出每个球染每个颜色的权值。染完色之后要重排成一个环,使得存在一组重排方案使得任意两个相邻球颜色不同。求权值极差最小值。 \(n,m \le 2000,a_{i,j}\le 10^6\)

key:尺取

题意即为任意颜色不能用超过 n/2 次。

考虑枚举最小值,找到对应的最小的最大值。现在即如何判定是否合法。

如果已知了最小值和最大值,现在要判定。

显然每个球要至少有一个可选颜色。

如果一个球只有一个颜色可选,那么这个球就只能是这个颜色。也就是说对于每个颜色,必选它的球的数目必须小于等于 n/2。现在所有的颜色必选它的球的数目都满足条件,如果对于所有颜色,可选它的球的数目小于等于 n/2,那么一定存在一组方案(显然);否则,即存在一个颜色,可选它的球的数目大于 n/2,以下分类讨论:

  1. 当 n 是偶数时,因为必选它的球的数目小于等于 n/2,那么我们可以恰好选它 n/2个,用其它颜色补剩下的(因为其他颜色不可能大于n/2)。
  2. 当 n 是奇数时,此时补全 n/2 后,剩下的球全选另一个颜色会出问题。而这种情况只会出现在仅用两个颜色时(如果用大于等于三种颜色,那么一定有一个可选颜色选第三种,不会出现这种情况)。

仔细观察上述的充要条件,我们我们只需要维护这么几个东西:

  1. 没有可选颜色的球的个数
  2. 对于每个颜色,必选它的球的个数
  3. 有多少个颜色,必选它的个数大于 n/2
  4. 有多少个颜色可选

对权值排序做双指针,每次是单点插入和删除,上述几个都可以 \(O(1)\) 实现。(对于每个球,加入颜色和删除颜色是按权值递增的;对于每个颜色,每次是必选它的球的个数加一或减一),所以瓶颈就是排个序。你可以用桶排做到 \(O(10^6+nm)\),不过没必要。

#include<bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<int,int> pii;
typedef pair<int,LL> pil;
const int SZ = 2e5 + 10;
const int mod = 1e9+7; LL read() {
LL n = 0;
char a = getchar();
bool flag = 0;
while(a > '9' || a < '0') { if(a=='-') flag = 1; a = getchar(); }
while(a <= '9' && a >= '0') { n=n*10+a-'0'; a = getchar(); }
if(flag) n=-n;
return n;
} int a[SZ],num,lim,colNum,col2[SZ]; void addCol(int x) {
// printf("add color: %d\n",x);
a[x] ++;
if(a[x] == lim) num ++;
} void delCol(int x) {
// printf("del color: %d\n",x);
if(a[x] == lim) num --;
a[x] --;
} int noMatchNumber;
queue<int> cols[SZ]; void init(int n,int m) {
for(int i = 1;i <= n;i ++) {
while(cols[i].size()) cols[i].pop();
}
noMatchNumber = n;
for(int i = 1;i <= m;i ++) {
a[i] = 0;
col2[i] = 0;
}
colNum = 0;
num = 0;
lim = n / 2 + 1;
} void add(pii p) {
int id = p.first,col = p.second;
if(col2[col] == 0) colNum ++;
col2[col] ++;
if(cols[id].size() == 0) {
noMatchNumber --;
addCol(col);
}
else if(cols[id].size() == 1) {
delCol(cols[id].front());
}
cols[id].push(col);
} void del(pii p) {
int id = p.first,col = p.second;
if(col2[col] == 1) colNum --;
col2[col] --;
assert(!cols[id].empty());
assert(cols[id].front() == col);
if(cols[id].size() == 1) {
noMatchNumber ++;
delCol(cols[id].front());
}
else if(cols[id].size() == 2) {
addCol(cols[id].back());
}
cols[id].pop();
} int n,m; bool check() {
if(noMatchNumber) return false;
if(num) return false;
if(n%2==1&&colNum <= 2) return false;
return true;
} int main() {
int T = read(),cc = 0;
while(T --) {
n = read(),m = read();
init(n,m);
vector<pair<int,pii> > a;
for(int i = 1;i <= n;i ++) {
for(int j = 1;j <= m;j ++) {
a.push_back(make_pair(read(),make_pair(i,j)));
}
}
sort(a.begin(),a.end());
int ans = 1e9;
//for(int i = 0;i < a.size();i ++) printf("%d: %d %d %d\n",i,a[i].first,a[i].second.first,a[i].second.second);
for(int i = 0,j = -1;i < a.size();i ++) {
while(!check() && j+1 < (int)a.size()) add(a[j+1].second),j ++;
if(!check()) break;
// printf("[%d,%d] %d\n",i,j,num);
ans = min(ans,a[j].first - a[i].first);
del(a[i].second);
}
if(ans == 1e9) ans = -1;
printf("Case %d: %d\n",++ cc,ans);
}
} /**
2
3 3
1 2 100
2 1 200
1 1 300 2 2 1
5 3
2 3 7
2 5 7
2 7 5
2 6 5
7 6 8 4 1
1
1
1
1 */

K

辣鸡模拟,咕

L

题意:给一个 n 个点的树,每个点有一个重量和价值。可以从树中选出一个独立集,定义 \(f(x)\) 为总重量为 x 的最大价值的方案数,求所有的 \(f(x) (1 \le x \le m)\) 。 \(n \le 50,m \le 5000\)

key:搜索,背包

先放个题解的 \(O(n^2m)\) 的做法:

普通树形背包复杂度 O(nm2),不可取。

考虑在 dfs 序上做 01 背包。

对整棵树做轻链剖分, dfs 先走轻儿子,最后再走重儿

子。这样从重儿子子树回溯的时候会直接回到重链顶端

我们所选独立集的后续发展与这条重链的中间节点是否

在独立集内没有关系。

从而背包是我们只要记下该节点的 log(n) 个重链顶端是

否在独立集内,该状态的大小为 2^log(n) = n。 dpi,mask,m 表

示走到 i 这个节点, log(n) 个重链顶端的状态为 mask,

所选重量为 m 的最有方案,直接背包。

没太懂那个 log 个重链……所以放个乱搞做法。

考虑折半,瓶颈在于对于两个点集的合并如何 check 是否是独立集。如果能模拟暴力背包的过程,那么只需要记录子树根节点选不选即可,这样合并两个背包是 max 卷积, \(O(m^2)\) 的复杂度。

考虑选重心为根节点,对每个子树暴力搜索独立集得到一个背包,之后按子树根节点选不选来讨论合并。这样能保证搜索最坏情况下是 \(2^{25}\) ,现在来看合并次数。

假设重心的每个子树大小都是 k ,那么搜索独立集的复杂度是 \(O(2^kn/k)\) ,迭代合并的复杂度是 \(O(nm^2/k)\) ,取等号时 k 在 25 左右,如果乘个 T 可能就不太行了。这个最坏情况是链。

子树比较小时可以用一些常数优化,比如只合并背包中合法的元素,合并子树时从小到大之类。

然而数据并没有卡这个乱搞所以就200+ms过了,我估计出题人也没想到

#include<bits/stdc++.h>
using namespace std; typedef long long LL;
typedef pair<int,int> pii;
typedef pair<int,LL> pil;
const int SZ = 2e5 + 10;
const int mod = 1e9+7; LL read() {
LL n = 0;
char a = getchar();
bool flag = 0;
while(a > '9' || a < '0') { if(a=='-') flag = 1; a = getchar(); }
while(a <= '9' && a >= '0') { n=n*10+a-'0'; a = getchar(); }
if(flag) n=-n;
return n;
} int n,m;
int A[55],B[55];
int mark[55],xl[55];
vector<int> nodelist,g[55]; void remark(int u,int f) {
nodelist.push_back(u);
for(int v : g[u]) {
if(v == f) continue;
remark(v,u);
}
} int sz[55]; void predfs(int u,int f) {
sz[u] = 1;
for(int v : g[u]) {
if(v == f) continue;
predfs(v,u);
sz[u] += sz[v];
}
} int get_centroid(int u) {
predfs(u,0);
int s = sz[u];
while(1) {
int found = 1;
for(int v : g[u]) {
if(sz[v] > sz[u]) continue;
if(sz[v] * 2 >= s) {
u = v; found = 0; break;
}
}
if(found) return u;
}
} pil up(pil a,pil b) {
pil ans;
ans.first = max(a.first,b.first);
if(a.first == ans.first) ans.second += a.second;
if(b.first == ans.first) ans.second += b.second;
if(!ans.second) ans.first = -1;
return ans;
} pil a[2][5010];
pil ans[2][5010];
pil tmp[2][5010]; void dfs(int d,int dn,int S,int sa,int sb) {
if(sa>m) return ;
if(d == dn) {
a[S&1][sa] = up(a[S&1][sa],make_pair(sb,1));
return ;
}
int u = nodelist[d];
if(!(xl[u] & S)) dfs(d+1,dn,S^(1<<mark[u]),sa+A[u],sb+B[u]);
dfs(d+1,dn,S,sa,sb);
} void work(int u,int r) {
nodelist.clear();
remark(u,r);
for(int i = 0;i < nodelist.size();i ++) mark[nodelist[i]] = i;
for(int u : nodelist) {
xl[u] = 0;
for(int v : g[u]) {
if(v == r) continue;
xl[u] ^= 1<<mark[v];
}
}
for(int i = 0;i < 2;i ++)
for(int j = 0;j <= m;j ++) {
tmp[i][j] = make_pair(-1,0);
a[i][j] = make_pair(-1,0);
}
dfs(0,nodelist.size(),0,0,0);
for(int x = 0;x < 2;x ++) {
for(int i = 0;i <= m;i ++) {
if(ans[x][i].second == 0) continue;
for(int y = 0;y < 2;y ++) {
if(x==1&&y==1) continue;
for(int j = 0;i+j <= m;j ++) {
if(a[y][j].second == 0) continue;
int sb = ans[x][i].first+a[y][j].first;
LL t = ans[x][i].second*a[y][j].second;
tmp[x][i+j] = up(tmp[x][i+j],make_pair(sb,t));
}
}
}
}
/*cout << u << endl;
for(int i = 0;i < 2;i ++) {
cout << i << endl;
for(int j = 0;j <= m;j ++) printf("%3d",a[i][j].first); puts("");
for(int j = 0;j <= m;j ++) printf("%3d",a[i][j].second); puts("");
}
for(int i = 0;i < 2;i ++) {
cout << i << endl;
for(int j = 0;j <= m;j ++) printf("%3d",ans[i][j].first); puts("");
for(int j = 0;j <= m;j ++) printf("%3d",ans[i][j].second); puts("");
}
for(int i = 0;i < 2;i ++) {
cout << i << endl;
for(int j = 0;j <= m;j ++) printf("%3d",tmp[i][j].first); puts("");
for(int j = 0;j <= m;j ++) printf("%3d",tmp[i][j].second); puts("");
}
puts("--------");*/
for(int i = 0;i < 2;i ++)
for(int j = 0;j <= m;j ++)
ans[i][j] = tmp[i][j];
} void bl() {
vector<pil> ans; ans.resize(m+1);
for(int S = 0;S < (1<<n);S ++) {
int sb = 0,sa = 0,b = 0;
for(int i = 0;i < n;i ++) {
if(S>>i&1) {
bool flag = 0;
for(int j : g[i+1]) if(S>>(j-1)&1) flag = 1;
if(flag) { b=1; break;}
sa += A[i+1];
sb += B[i+1];
}
}
if(b) continue;
if(sa>m) continue;
if(ans[sa].first < sb) ans[sa] = make_pair(sb,1);
else if(ans[sa].first == sb) ans[sa].second ++;
}
for(int i = 1;i <= m;i ++) printf("%lld ",ans[i].second); puts("");
} int main() {
int T = read(),cc = 0;
while(T --) {
n = read(),m = read();
for(int i = 1;i <= n;i ++) A[i]=read(),B[i]=read();
for(int i = 1;i <= n;i ++) g[i].clear();
for(int i = 1;i < n;i ++) {
int x = read(),y = read();
g[x].push_back(y);
g[y].push_back(x);
}
int rt = get_centroid(1);
predfs(rt,0);
sort(g[rt].begin(),g[rt].end(),[](int x,int y) {return sz[x] < sz[y];});
for(int i = 0;i <= m;i ++) {
ans[0][i] = ans[1][i] = make_pair(-1,0);
}
ans[0][0] = make_pair(0,1);
ans[1][A[rt]] = make_pair(B[rt],1);
// cout << rt << endl;
for(int x : g[rt]) work(x,rt);
printf("Case %d:\n",++ cc);
for(int i = 1;i <= m;i ++) {
pil x = up(ans[0][i],ans[1][i]);
printf("%lld%c",x.second,i==m?'\n':' ');
}
//bl();
}
} /**
1
4 5
1 1
2 2
3 2
2 1
1 2
2 3
3 4 3
3 2
1 1
1 1
1 1
1 2
1 3
4 5
1 1
2 2
3 2
2 1
1 2
2 3
3 4
5 10
3 1
2 2
4 4
7 8
5 16
1 2
1 3
2 4
2 5
*/

2018CCPC吉林赛区 hdu6555~hdu6566的更多相关文章

  1. 2018CCPC吉林赛区 | 部分题解 (HDU6555 HDU6556 HDU6559 HDU6561)

    // 杭电上的重现赛:http://acm.hdu.edu.cn/contests/contest_show.php?cid=867 // 杭电6555~6566可交题 A - The Fool 题目 ...

  2. [2018CCPC吉林赛区(重现赛)- 感谢北华大学] 补题记录 躁起来

    1007 High Priestess 埃及分数 1008 Lovers 线段树维护取膜意义下的区间s和. 每个区间保存前缀lazy和后缀lazy. #include <iostream> ...

  3. 2018CCPC吉林赛区

    传送门 A - The Fool 整除分块即可. B - The World 模拟即可. C - Justice 题意: 给出\(n\)个数\(k_i\),每个数的权值为\(\frac{1}{2^{k ...

  4. 2018CCPC吉林赛区(重现赛)

    http://acm.hdu.edu.cn/contests/contest_show.php?cid=867 A题,直接分块,不知道正解是什么. #include<bits/stdc++.h& ...

  5. 2018CCPC吉林赛区(重现赛)部分题解

    The Fool 题目链接 Problem Description The Fool is numbered 0 – the number of unlimited potential –and th ...

  6. 2018CCPC 吉林现场赛 赛后总结

    一直以来都没有比赛完写总结的习惯,导致前面几次比赛都没有写过总结. 这是我写的第一场总结把,有时间有想法还记得细节的话再把前面几次比赛的总结给补上把. 热身赛: 热身赛的时候,写的比较急想着快点做出题 ...

  7. HDU 6556 (2018CCPC吉林 B题)

    ### HDU 6556 题目链接 ### 题目大意: 给你四个国家的时区,告诉你 A 国家的时间,让你输出这时候在 B 国家的时间,还需要输出对于 A 国家来说这是 昨天.今天 还是 明天. 分析前 ...

  8. 2018ccpc吉林 E:THE TOWER——数形结合

    题目 链接 给你一个圆锥(位于坐标原点,告诉你高h 和底面半径 r),和一个点(x,y,z)并告诉你这个点的速度, 让你求点和圆锥相撞的最小时间(保证一定相撞) 分析 易知,将直线的参数方程与圆锥曲面 ...

  9. HDU 6562 lovers 2018CCPC吉林H(线段树)

    题意: 初始n个空串,m个操作: 1.给[l,r]的所有字符串头尾加一个‘d’,将原字符串x变为dxd 2.求[l,r]所有字符串代表的数字之和mod 1e9+7 思路: 据说是硬核线段树.. 对于线 ...

随机推荐

  1. 记一次Redis+Getshell经验分享

    前言: 当我们接到一个授权渗透测试的时候,常规漏洞如注入.文件上传等尝试无果后,扫描端口可能会发现意外收获. 知己知彼乃百战不殆,Redis介绍: 简单来说 redis 就是一个Key-Value类型 ...

  2. 桌面右键没有新建txt文本文档的快捷方式、

    先新建一个word文档,然后将后缀名改为 TXT. 在里面输入:Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\.txt] @=&quo ...

  3. Vmware 和 VisualSVN-Server端口冲突

    安装 VisualSVN-Server 时,发现他和 Vmware   在端口  443 冲突: 先把本地自启动的 Vmware 全部停止,并改成手工启动服务: 这样可以节省资源,再安装 svn服务时 ...

  4. oracle通用帮助类

    需要的dll( EntityFramework.6.0.0Oracle.ManagedDataAccess.12.1.2400System.Configuration.dllEmitMapper.1. ...

  5. leetcode1 twoSum

    """ Given an array of integers, return indices of the two numbers such that they add ...

  6. redis.conf文件配置

    最重要三个配置 1. bind 127.0.0.1 需要注释掉这一行,使别的主机可以访问 2. daemonize no 需要改为yes,使其后台运行 3. requirepass foobared ...

  7. 51nod 1293:球与切换器

    1293 球与切换器 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  取消关注 有N行M列的正方形盒子.每个盒子有三种状态0 ...

  8. 侯捷C++学习(二)

    #include <iostream>using namespace std;class complex{ public: complex (double r= 0, double i = ...

  9. bzoj 2451 Uyuw's Concert

    裸的半平面交.感觉这些东西,纯属在考代码能力啊.. #include<cstdio> #include<algorithm> #include<cmath> #de ...

  10. php知识结构

    PHP的运行环境 连环境都搞不起来,就是你有多么喜欢PHP,那也是白搭,开始我们大多会使用集成环境软件例如xampp,wamp.随着知识的增加慢慢要学会自己搭建运行环境,例如 Linux(Ubuntu ...