Gym 101482 题解
B:Biking Duck
题意:现在有一个人要从(x1,y1)点走到(x2,y2)点, 现在走路的速度为v。 还有骑自行车的速度v2,自行车要从某个自行车站到另一个自行车站,现在我们可以视地图的边界都为自行车站,求最小时间是多少。
题解:对于忽视边界的问题,那就是暴力枚举。现在有了边界, 我们假设一个点在边界,那么我们可以枚举另一个自行车点之后,在某个边界上三分另一个点。 下一个情况就是2个自行车站都在边界上,我们三分套三分去维护找到最小值。
思维不怎么麻烦,就是写的有点麻烦。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<double,double> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
pll p[N], x, y, ld, ru;
double v1, v2;
int n;
double dis(pll p1, pll p2){
return sqrt(pow(p1.fi-p2.fi,)+pow(p1.se-p2.se,));
}
double cal(pll p1, pll p2, int fx){
if(fx == || fx == ){
double posy;
if(fx == ) posy = ld.se;
else posy = ru.se;
double lx = ld.fi, rx = ru.fi;
for(int i = ; i < ; ++i){
double m = (lx+rx)/2.0;
double mm = (m+rx)/2.0;
if((dis(p1,{m,posy})/v2+dis(p2,{m,posy})/v1) > (dis(p1,{mm,posy})/v2+dis(p2,{mm,posy})/v1)) lx = m;
else rx = mm;
}
return dis(p1,{lx,posy})/v2 + dis(p2,{lx,posy})/v1;
}
else {
double posx;
if(fx == ) posx = ld.fi;
else posx = ru.fi;
double ly = ld.se, ry = ru.se;
for(int i = ; i < ; ++i){
double m = (ly+ry)/2.0;
double mm = (m+ry)/2.0;
if(dis(p1,{posx,m})/v2 + dis(p2,{posx,m})/v1 > dis(p1,{posx,mm})/v2 + dis(p2,{posx,mm})/v1) ly = m;
else ry = mm;
}
return dis(p1,{posx,ly})/v2 + dis(p2,{posx,ly})/v1;
}
}
double solve(int fx, int ffx){
if(fx == || fx == ){
double posy;
if(fx == ) posy = ld.se;
else posy = ru.se;
double lx = ld.fi, rx = ru.fi;
for(int i = ; i < ; ++i){
double m = (lx+rx)/2.0;
double mm = (m+rx)/2.0;
if(dis(x,{m,posy})/v1+cal({m,posy},y,ffx) > dis(x,{mm,posy})/v1+cal({mm,posy},y,ffx)) lx = m;
else rx = mm;
} return dis(x,{lx,posy})/v1+cal({lx,posy},y,ffx);
}
else {
double posx;
if(fx == ) posx = ld.fi;
else posx = ru.fi;
double ly = ld.se, ry = ru.se;
for(int i = ; i < ; ++i){
double m = (ly+ry)/2.0;
double mm = (m+ry)/2.0;
if(dis(x,{posx,m})/v1+cal({posx,m},y,ffx) > dis(x,{posx,mm})/v1+cal({posx,mm},y,ffx)) ly = m;
else ry = mm;
}
return dis(x,{posx,ly})/v1+cal({posx,ly},y,ffx);
}
}
int main(){
scanf("%lf%lf", &v1, &v2);
scanf("%lf%lf", &ld.fi, &ld.se);
scanf("%lf%lf", &ru.fi, &ru.se);
scanf("%lf%lf", &x.fi, &x.se);
scanf("%lf%lf", &y.fi, &y.se);
scanf("%d", &n);
for(int i = ; i <= n; ++i)
scanf("%lf%lf", &p[i].fi, &p[i].se);
double ans = dis(x,y)/v1;
for(int i = ; i <= n; ++i)
for(int j = ; j <= n; ++j){
double tmp = dis(p[i],p[j])/v2+(dis(p[i],x)+dis(p[j],y))/v1;
ans = min(ans, tmp);
}
for(int i = ; i <= n; ++i){
ans = min(ans, dis(x,p[i])/v1+cal(p[i],y,));
ans = min(ans, dis(x,p[i])/v1+cal(p[i],y,));
ans = min(ans, dis(x,p[i])/v1+cal(p[i],y,));
ans = min(ans, dis(x,p[i])/v1+cal(p[i],y,)); ans = min(ans, dis(y,p[i])/v1+cal(p[i],x,));
ans = min(ans, dis(y,p[i])/v1+cal(p[i],x,));
ans = min(ans, dis(y,p[i])/v1+cal(p[i],x,));
ans = min(ans, dis(y,p[i])/v1+cal(p[i],x,));
}
for(int i = ; i <= ; ++i){
for(int j = ; j <= ; ++j){
ans = min(ans, solve(i,j));
}
}
printf("%.10f\n", ans);
return ;
}
C:Cent Savings
题意:将传送带上的物品最多分成m+1个部分,每部分单独付费这个付费是四舍五入,然后问最小花费是多少。
题解: DP跑一下花费。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 2e3 + ;
int a[N], b[N];
int dp[N][];
int main(){
int n, m;
int ans = ;
memset(dp, inf, sizeof(dp));
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i){
scanf("%d", &a[i]);
ans += a[i] / ;
a[i] %= ;
b[i] = b[i-] + a[i];
}
ans *= ;
dp[][] = ;
for(int i = ; i <= n; ++i){
for(int l = ; l <= i; ++l){
int sum = b[i] - b[l-];
int t = sum % ;
if(t > ) sum = sum + - t;
else sum -= t;
for(int k = ; k <= m; ++k)
dp[i][k+] = min(dp[i][k+], sum + dp[l-][k]);
}
}
int fans = inf;
for(int i = ; i <= m+; ++i){
fans = min(fans, dp[n][i]);
}
cout << ans+fans << endl;
return ;
}
D:Digi Comp II
题意:现在有N个板子,每个板子都有一个朝向,每次一个求落在板子上,求会掉到现在的方向的这一边,然后板子换一个方向,现在落下n个球,问最后所有板子的方向。
题解:模拟, 按照toposort的方式处理就好了。 注意就是左边和右边都有可能是指向同一个新的板子。
所以不能先把所有板子都 --度数之后,再入队。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 5e5 + ;
LL a[N]; LL n;
int vis[N], m, d[N];
int to[N][];
void toposort(){
queue<int> q;
for(int i = ; i <= m; ++i){
if(!d[i]) q.push(i);
}
while(!q.empty()){
int x = q.front();
q.pop();
a[to[x][]] += a[x]/;
a[to[x][]] += a[x]/;
if(a[x]&){
a[to[x][vis[x]]]++;
vis[x] ^= ;
}
--d[to[x][]];
if(d[to[x][]] == ) q.push(to[x][]);
--d[to[x][]];
if(d[to[x][]] == ) q.push(to[x][]);
}
}
int main(){
scanf("%lld%d", &n, &m);
char op[];
for(int i = ; i <= m; ++i){
scanf("%s", op);
if(op[] == 'L') vis[i] = ;
else vis[i] = ;
scanf("%d%d", &to[i][], &to[i][]);
++d[to[i][]];
++d[to[i][]];
}
a[] = n;
toposort();
for(int i = ; i <= m; ++i)
printf("%c","LR"[vis[i]]);
return ;
}
E:Euclidean TSP
题意:找到一个的c使得题目中的2个式子之和最小。
题解:3分答案,这一定是一个凹函数。
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0)
using namespace std; double n, p, s, v;
double f(double c) {
double t1 = (n * pow(log(n) / log(), c * sqrt())) / (p * 1e9);
double t2 = s * (1.0 + 1.0 / c) / v;
return t1 + t2;
}
int main() {
scanf("%lf%lf%lf%lf", &n, &p, &s, &v);
double l = , r = 1e30;
for (int i = ; i < 1e4; i++) {
double ll = (l + r) / ;
double rr = (ll + r) / ;
if (f(ll) > f(rr)) l = ll;
else r = rr;
}
printf("%f %f\n", f(l), l);
}
F:Finding Lines
题意:给你n个点,然后在让你添加上p个点,问你能不能满足至少一条直线上出现 (n+3)/4 个点。
题解:随机生成p个点500次, 然后check。
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0)
using namespace std; const int N = 1e5 + ;
typedef long long ll;
struct point {
ll x, y;
point (ll _x = , ll _y = ) :x(_x), y(_y) {}
void read() {
scanf("%I64d%I64d", &x, &y);
}
void out() {
cout<<"x = "<<x<<" y = "<<y<<endl;
}
point operator - (const point &rhs) const {
return point(x - rhs.x, y - rhs.y);
}
}p[N]; ll cross(point a, point b) {
return a.x * b.y - a.y * b.x;
} int n, percent, need;
int main() {
srand(time(NULL));
scanf("%d%d", &n, &percent);
for (int i = ; i < n; i++) p[i].read();
if (n <= ) {
puts("possible");
return ;
}
int need = (n * percent) / ;
if ((n * percent) % != ) need++;
int mx = ;
for (int _ = ; _ < ; _++) {
random_shuffle(p, p + n);
int cnt = ;
for (int i = ; i < n; i++) if (cross(p[] - p[], p[i] - p[]) == ) cnt++;
if (cnt >= need) {
puts("possible");
return ;
}
mx = max(mx, cnt);
}
puts("impossible");
return ;
}
G:Gathering
题意:在平面上有n个点,然后现在让你找到一个点,使得所有点到这个点的曼哈顿距离只和最小,且不能有距离>d的点。
题解:如果我们不考虑距离 > d的情况下, 那么最优解肯定就是所有点的x值的中位数, y值的中位数。
现在我们多了一个限制性的条件, 那么我们先把这个可行域扣出来,可行域是一个斜着的正方形,那么最优解的那个点如果落在可行域之内,那么就是这个点, 但是如果落在外面的话,就会存在一种现象,如果当x更靠近最优解的点的时候, y可能会变得更远。
对于上面的那个东西来说, 他会形成一个凹函数, 这个地方我们可以用三分去找到答案。
我们每次三分x轴, 当x轴定下来之后,那么y就自然是选择可行范围内的位置中更靠近最优解的点,所以只需要一个三分就好了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
int x[N], y[N];
LL A = INF, B = -INF, C = -INF, D = INF;
LL midy;
int n;
LL cal(LL xx){
LL uy = min(xx-C, A-xx);
LL dy = max(B-xx, xx-D);
if(uy < dy) return INF;
LL ty;
if(midy > uy) ty = uy;
else if(midy < dy) ty = dy;
else ty = midy;
LL ret = ;
for(int i = ; i <= n; ++i){
ret += abs(x[i]-xx) + abs(y[i]-ty);
}
return ret;
}
int main(){
scanf("%d", &n);
for(int i = ; i <= n; ++i)
scanf("%d%d", &x[i], &y[i]);
LL d;
scanf("%lld", &d);
for(int i = ; i <= n; ++i){
A = min(A, x[i]+y[i]+d); B = max(B, x[i]+y[i]-d);
C = max(C, x[i]-y[i]-d); D = min(D, x[i]-y[i]+d);
}
//cout << A << ' ' << B << ' '<< C << ' ' << D << endl;
if(A < B || C > D) {
puts("impossible");
return ;
}
sort(y+, y++n);
midy = y[(n+)/];
LL lx = (C+B)/, rx = (A+D)/;
//cout << lx << ' ' << rx << endl;
while(lx + < rx){
LL lm = (lx+rx)/ , rm = (lm+rx)/;
if(cal(lm) < cal(rm)) rx = rm;
else lx = lm;
}
LL ans = INF;
for(lx; lx <= rx; ++lx) ans = min(ans, cal(lx));
printf("%lld\n", ans);
return ;
}
H:Hyacinth
题意:给你一棵树,对于这棵树来说,每一个端点来说是有2个频率,任意2个相连的点,至少要有一个频率是相同的,一个频率如果有效,那么至少出现在一对相邻的点上,求一种构造方式使得有效频率最多。
题解:先找到一个根,然后对于根来说随意分配2个值,然后对于一个新的点来说,先找到父亲的2个频率没出现2次的,找不到就随便一个,然后如果这个点有儿子,那么就来一个新的频率,如果没有儿子就把这个点的另一个频率赋值给这个点。
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
pll p[N];
vector<int> vc[N];
int tot;
int vis[N];
queue<int> q;
void dfs(int o, int u){
if(u == ) {
p[u].fi = ;
p[u].se = ;
vis[] = vis[] = ;
tot = ;
for(auto v : vc[u]){
dfs(u, v);
}
}
else {
if(vc[u].size() == ){
p[u] = p[o];
++vis[p[u].fi];
++vis[p[u].se];
return ;
}
if(vis[p[o].fi] >= )
p[u].fi = p[o].se;
else
p[u].fi = p[o].fi;
vis[p[u].fi]++;
p[u].se = tot++;
vis[p[u].se]++;
for(auto v : vc[u]){
if(v == o) continue;
dfs(u, v);
}
}
}
int pp = ; int main(){
int n;
scanf("%d", &n);
for(int i = , u, v; i < n; ++i){
scanf("%d%d", &u, &v);
vc[u].pb(v); vc[v].pb(u);
}
dfs(,);
for(int i = ; i <= n; ++i){
printf("%d %d\n", p[i].fi, p[i].se);
}
return ;
}
I:Indoorienteering
题意:有一副 n 个点的完全图,问你是否存在某个路使得,从某点出发,跑一圈会到这个点,其他点都恰好经过一次,且总路程为L。
题解:对于这个东西,我们把这幅图割成2部分,1号点一定在左边,并且一定是这幅图的起点,我们枚举左边图的状态, 枚举左边图的另一个端点,然后爆搜右边图的状态,然后在爆搜左边图的确定端点之后的状态,然后二分check。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = ;
LL d[N][N], l;
int lf[N], lsz, rt[N], rsz;
LL vc[], vsz;
void cal(int b, int e){
vsz = ;
do{
LL cnt = ;
cnt += d[b][rt[]] + d[e][rt[rsz]];
for(int i = ; i <= rsz; ++i)
cnt += d[rt[i-]][rt[i]];
vc[++vsz] = cnt;
}while(next_permutation(rt+,rt++rsz));
sort(vc+, vc++vsz);
vsz = unique(vc+, vc++vsz) - vc - ;
}
int c[N], csz;
inline bool bck(LL v){
if(v <= ) return false;
int p = lower_bound(vc+, vc++vsz, v) - vc;
if(vc[p] == v) return true;
return false;
}
void check(int u, int v){
csz = ;
for(int i = ; i <= lsz; ++i){
if(lf[i] == u || lf[i] == v) continue;
c[++csz] = lf[i];
}
if(csz){
do{
LL tmp = l;
tmp -= d[u][c[]] + d[v][c[csz]];
for(int i = ; i <= csz; ++i){
tmp -= d[c[i-]][c[i]];
}
if(bck(tmp)){
puts("possible");
exit();
}
}while(next_permutation(c+, c++csz));
}
else{
if(bck(l-d[u][v])){
puts("possible");
exit();
}
}
}
void solve(){
int t = -;
for(int i = ; i <= lsz; ++i){
t = lf[i];
cal(,t);
check(,t);
}
if(t == -) {
cal(,);
check(,);
}
}
int main(){
int n;
scanf("%d%lld", &n, &l);
for(int i = ; i < n; ++i)
for(int j = ; j < n; ++j)
scanf("%lld", &d[i][j]);
int lnum = n/ , rnum = n - lnum;
int m = (<<n);
for(int i = ; i < m; ++i){
lsz = rsz = ;
for(int j = ; j < n; ++j){
if((i>>j)&) lf[++lsz] = j;
else rt[++rsz] = j;
}
if(lsz == lnum && lf[] == )
solve();
}
puts("impossible");
return ;
}
J:Judging Troubles
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0)
using namespace std; map<string, int>mp1, mp2;
int n, ans;
int main() {
fio;
cin>>n;
string tmp;
for (int i = ; i < n; i++) {
cin>>tmp;
mp1[tmp]++;
}
for (int i = ; i < n; i++) {
cin>>tmp;
mp2[tmp]++;
}
for (auto it = mp1.begin(); it != mp1.end(); ++it) {
ans += min(it->second, mp2[it->first]);
}
cout<<ans<<endl;
}
K:Knapsack Collection
题意:现在有一个长度为s的传送带,传送带上有n个物品,每个物品的位置在pi,现在每次拿一个物品要t秒,如果你站在传送带的位置上,那么你就会有东西传到你的面前,然后你就会用t的时间去拿这个东西。现在对于传送带的每个位置,你都会有一个拿完所有的物品的花费时间, 现在问你这个花费时间最小是多少, 最大是多少, 平均时间是多少。
题解:我们枚举所有从所有有东西的位置开始,最小的时间一定会是从某个有东西的位置开始的,然后最大的时间一定是某个有东西的位置的后面,我们算出所有有东西的状态,然后上一个位置如果没有东西,就是这个位置的状态+1。
然后我们就模拟拿东西的过程,我们可以把自己不动传送带动的方式 -> 传送带不动 自己动来模拟。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = ;
int cnt[N];
int a[N];
LL tim[N];
int n, s, t;
LL cal(int x){
LL ret = ; int p = x;
multiset<int> st;
multiset<int>::iterator it;
for(int i = ; i <= n; ++i) st.insert(a[i]);
while(!st.empty()){
it = st.lower_bound(p);
if(it == st.end()){
ret += s - p;
p = ;
it = st.lower_bound(p);
}
ret += (*it) - p + t;
p = ((*it)+t) % s;
st.erase(it);
}
return ret;
}
int main(){
scanf("%d%d%d", &n, &s, &t);
for(int i = ; i <= n; ++i)
scanf("%d", &a[i]);
sort(a+, a++n);
a[] = -;
LL sum = ;
for(int i = ; i <= n; ++i){
if(a[i] == a[i-]) tim[i] = tim[i-];
else {
tim[i] = cal(a[i]);
//sum += tim[i];
}
}
LL mn = tim[], mx = tim[];
for(int i = ; i <= n; ++i){
mn = min(mn, tim[i]);
mx = max(mx, tim[i]);
}
for(int i = ; i <= n; ++i){
if(a[i] == a[i-]) continue;
int l = a[i-] + , r = a[i];
if(l == -) l = a[n] + , r += s;
//cout << l << ' ' << r << endl;
int len = r - l + ;
mx = max(mx, tim[i]+len-);
sum += 1ll * (tim[i]+tim[i]+len-) * len / ;
}
cout << mn << endl;
cout << mx << endl;
LL gcd = __gcd(sum, 1ll*s);
sum /= gcd;
s /= gcd;
cout << sum << '/' << s << endl;
return ;
}
Gym 101482 题解的更多相关文章
- Northwestern European Regional Contest 2014 Gym - 101482
Gym 101482C Cent Savings 简单的dp #include<bits/stdc++.h> #define inf 0x3f3f3f3f #define inf64 0x ...
- Gym 100851 题解
A: Adjustment Office 题意:在一个n*n的矩阵,每个格子的的价值为 (x+y), 现在有操作取一行的值,或者一列的值之后输出这个和, 并且把这些格子上的值归0. 题解:模拟, 分成 ...
- Gym 101470 题解
A:Banks 代码: #include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt&q ...
- Gym 101964 题解
B:Broken Watch (别问,问就是队友写的) 代码: import java.awt.List; import java.io.BufferedInputStream; import jav ...
- 2016-2017 National Taiwan University World Final Team Selection Contest (Codeforces Gym) 部分题解
D 考虑每个点被删除时其他点对它的贡献,然后发现要求出距离为1~k的点对有多少个. 树分治+FFT.分治时把所有点放一起做一遍FFT,然后减去把每棵子树单独做FFT求出来的值. 复杂度$nlog^ ...
- 2016百度之星 初赛2A ABEF
只做了1001 1002 1005 1006.剩下2题可能以后补? http://acm.hdu.edu.cn/search.php?field=problem&key=2016%22%B0% ...
- Codeforces Gym 102361A Angle Beats CCPC2019秦皇岛A题 题解
题目链接:https://codeforces.com/gym/102361/problem/A 题意:给定二维平面上的\(n\)个点,\(q\)次询问,每次加入一个点,询问平面上有几个包含该点的直角 ...
- Codeforces GYM 100876 J - Buying roads 题解
Codeforces GYM 100876 J - Buying roads 题解 才不是因为有了图床来测试一下呢,哼( 题意 给你\(N\)个点,\(M\)条带权边的无向图,选出\(K\)条边,使得 ...
- Codeforces Gym 102392F Game on a Tree (SEERC2019 F题) 题解
题目链接:https://codeforces.com/gym/102392/problem/F 题意:被这题题意坑了很久,大意是说有一棵根为 \(1\) 的树,每个节点初始都是白色, \(Alice ...
随机推荐
- PHP编码风格规范
由于PHP的灵活性,很多人写起代码来也不讲求一个好的代码规范,使得本就灵活的PHP代码看起来很乱,其实PSR规范中的PSR-1和PSR-2已经定义了在PHP编码中的一些规范,只要我们好好遵守这些规范, ...
- Linux内核OOM killer机制
程序运行了一段时间,有个进程挂掉了,正常情况下进程不会主动挂掉,简单分析后认为可能是运行时某段时间内存占用过大,系统内存不足导致触发了Linux操作系统OOM killer机制,将运行中的进程杀掉了. ...
- Mysql执行过程总结
总分三个阶段:Sql的解析,执行和结果获取阶段. 如下图,展开相熟.
- go单元测试
testing模块 测试代码放在当前包以_test.go结尾的文件中 测试函数以Test为名称前缀 测试命令(go test) 正常编译操作(go build/install)会忽略测试文件 单例模式 ...
- Linux基础进程管理
一.进程 了解如进程的: • PID,PPID • 当前的进程状态 • 内存的分配情况 • CPU和已花费的实际时间 • 用户UID,他决定进程的特权 (一).静态查看进程 # ps axu | le ...
- MRCPv2在电信智能语音识别业务中的应用
1. MRCPv2协议简介 媒体资源控制协议(Media Resource Control Protocol, MRCP)是一种基于TCP/IP的通讯协议,用于客户端向媒体资源服务器请求提供各种媒体资 ...
- Intent 常用方法总结
极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本文主要是总结Intent 常用的方法,并封装成Utils类中 主要涉及以下内容 ...
- 自定义ItemToggleView
极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...
- Docker启用TLS进行安全配置
之前开启了docker的2375 Remote API,接到公司安全部门的要求,需要启用授权,翻了下官方文档 Protect the Docker daemon socket 启用TLS 在docke ...
- git语句(后续补充)
如果你是windows用户,需要下载一个git应用程序,一路点就行,没有什么需要注意的地方 安装完成后在任一文件夹内右键都有显示,单击git bash here即可 简易的命令行入门教程: Git 全 ...