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. springboot的maven多模块项目架构微服务搭建——依赖方式的多模块演化为微服务项目

    在上一篇依赖方式多模块的基础上对项目进行改造.主要改造user-service项目,service要配置mapper.mybatis及数据库相关的东西,后面的接口消费方user就不再需要了 注意:以下 ...

  2. [Luogu][P2458] [SDOI2006]保安站岗

    题目链接 看起来似乎跟最小点覆盖有点像.但区别在于: 最小点覆盖要求所有边在其中,而本题要求所有点在其中. 即:一个点不选时,它的儿子不一定需要全选. 画图理解: 对于这样一幅图,本题中可以这样选择: ...

  3. 使用python将请求的requests headers参数格式化方法

    import json # 使用三引号将浏览器复制出来的requests headers参数赋值给一个变量 headers = """ Host: zhan.qq.com ...

  4. NPOI读取excel 空行

    if (sheet.GetRow(i) != null) 每行判断一下,避免出错.真是蛋疼.

  5. NIO 聊天室代码实现

    服务器端 package com.ronnie.nio.groupChat; import java.io.IOException; import java.net.InetSocketAddress ...

  6. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-trash

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  7. P1040 有几个PAT

    转跳点:

  8. 编码解码:UrlDecode解码及UrlEncode编码的jQuery方法

    找了n多方法,终于找到,不容易. C#:Server.UrlEncode(ur) Jquery解码:decodeURIComponent(url); Jquery编码:encodeURICompone ...

  9. netty权威指南学习笔记三——TCP粘包/拆包之粘包现象

    TCP是个流协议,流没有一定界限.TCP底层不了解业务,他会根据TCP缓冲区的实际情况进行包划分,在业务上,一个业务完整的包,可能会被TCP底层拆分为多个包进行发送,也可能多个小包组合成一个大的数据包 ...

  10. 解决dispatch 后在当前页面不能获取最新的this.props中的数据

    因为dispatch为异步方法  .解决这个问题方法很多  出去添加定时器这种不是很优雅的方法  我们可以用 componentWillReceiveProps(nextProps) 这个生命周期  ...