NCD 2019 (AK)
A. Hasan the lazy judge
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; inline int read(){ int x=0; bool f=0; char ch=getchar(); while (ch<'0' || '9'<ch) f|=ch=='-', ch=getchar(); while ('0'<=ch && ch<='9') x=x*10+ch-'0', ch=getchar(); return f?-x:x; } const int maxn = 1e5 + 10; int T, n, m; int c[maxn]; int limit; int lowbit(int x) { return x & (-x); } void update(int p, int v) { for(int i = p; i <= limit; i = i + lowbit(i)) { c[i] += v; } } int sum(int p) { int ans = 0; while(p >= 1) { ans += c[p]; p -= lowbit(p); } return ans; } struct H { int x1, x2, y; } h[maxn]; struct V { int y1, y2, x; } v[maxn]; struct F {int x, y; } in[maxn], out[maxn]; bool cmp(const V& v1, const V& v2) { return v1.x < v2.x; } bool cmpf(const F& v1, const F& v2) { return v1.x < v2.x; } bool check(int len) { bool res = 0; int in_index = 0; int out_index = 0; for(int i = 1; i <= n; i ++) { if(h[i].x2 - h[i].x1 < 2 * len) continue; in_index ++; in[in_index].x = h[i].x1 + len; in[in_index].y = h[i].y; out_index ++; out[out_index].x = h[i].x2 - len; out[out_index].y = h[i].y; } sort(in + 1, in + in_index + 1, cmpf); sort(out + 1, out + out_index + 1, cmpf); int in_i = 1, out_i = 1; for(int j = 1; j <= m; j ++) { if(v[j].y2 - v[j].y1 < 2 * len) continue; while(in_i <= in_index && in[in_i].x <= v[j].x) { update(in[in_i].y, 1); in_i ++; } while(out_i <= out_index && out[out_i].x < v[j].x) { update(out[out_i].y, -1); out_i ++; } if(sum(v[j].y2 - len) - sum(v[j].y1 + len - 1) != 0) res = 1; } while(in_i <= in_index) { update(in[in_i].y, 1); in_i ++; } while(out_i <= out_index) { update(out[out_i].y, -1); out_i ++; } return res; } int main() { scanf("%d", &T); for(int cas = 1; cas <= T; cas ++) { int L = 0, R = 0, ans = 0; limit = 0; scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++) { h[i].x1 = read(); h[i].x2 = read(); h[i].y = read(); if(h[i].x2 < h[i].x1) swap(h[i].x1, h[i].x2); R = max(R, (h[i].x2 - h[i].x1) / 2); limit = max(limit, h[i].x2); } for(int j = 1; j <= m; j ++) { v[j].y1 = read(); v[j].y2 = read(); v[j].x = read(); if(v[j].y2 < v[j].y1) swap(v[j].y1, v[j].y2); R = max(R, (v[j].y2 - v[j].y1) / 2); limit = max(limit, v[j].x); } sort(v + 1, v + m + 1, cmp); while(L <= R) { int mid = (L + R) / 2; if(check(mid)) { ans = mid; L = mid + 1; } else { R = mid - 1; } } printf("%d\n", ans); } return 0; }
B. Let me sleep
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//1170ms 43.9MB #include <cstdio> #include <algorithm> #include <vector> #include <cstring> #include <stack> using namespace std; const int maxn=2e5+100; const int maxe=1e6+100; struct edge//邻接表表示图 { int to,next; int flag;//访问标记 }e[maxe<<1]; int head[maxn],cnt; stack<int> sta; int dfn[maxn],low[maxn],belong[maxn],index,n,m,sum,scc; int fa[maxn];//父结点 int bridge[maxn][2]; void init()//初始化 { memset(head,-1,sizeof(head)); cnt=-1;//边编号 scc=0;//边双连通分量编号 index=0;//深度 sum=0;//桥总数 memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(fa,0,sizeof(fa)); } void add_edge(int u,int v)//加边 { e[++cnt].to=v; e[cnt].flag=0;//标记该无向边是否被访问过,将正向边和反向边一起标记 e[cnt].next=head[u]; head[u]=cnt; } void tarjan(int u,int f)//dfs确定边双连通分量和桥 { dfn[u]=low[u]=++index; sta.push(u); for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].to; if(e[i].flag) continue;///只能跳过反向边,不能跳过重边 ///注意重边,边(u,v)有重边,其不可能是桥,重边相当于两点之间的另一条路,不能合并 e[i].flag=e[i^1].flag=1; if(dfn[v]) low[u]=min(low[u],dfn[v]); else { tarjan(v,u); fa[v]=u; low[u]=min(low[u],low[v]); if(low[v]>dfn[u])//桥的判断条件 { sum++; //存桥,然后根据桥去建新图 bridge[sum][0]=u; bridge[sum][1]=v; } } } if(dfn[u]==low[u])//双连通分量 { scc++; while(!sta.empty()) { int p=sta.top();sta.pop(); belong[p]=scc; if(p==u) break; } } } int node,d[maxn],ans; void dfs(int u,int dist)//dfs确定每个结点距初始结点的距离 { d[u]=dist; if(d[u]>ans) ans=d[u],node=u; for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].to; if(d[v]!=-1) continue; dfs(v,dist+1); } } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d%d",&n,&m); if(n==0 && m==0) break; init(); while(m--)//建图 { int u,v; scanf("%d%d",&u,&v); add_edge(u,v); add_edge(v,u); } for(int i=1;i<=n;i++)//初始图不一定连通 if(!dfn[i]) tarjan(i,0);//tarjan算法求所有双连通分量和桥 //根据桥建新图 memset(head,-1,sizeof(head)); cnt=-1; for(int i=1;i<=sum;i++) { int u=belong[bridge[i][0]]; int v=belong[bridge[i][1]]; add_edge(u,v); add_edge(v,u); } //两遍dfs求树直径 ans=0; memset(d,-1,sizeof(d)); dfs(1,0);//从根到最远点node memset(d,-1,sizeof(d)); ans=0; dfs(node,0);//从最远点到另一个最远点 printf("%d\n",sum-ans); } return 0; }
C. Hasan and his lazy students
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; const int maxn = 1010; const int mod = 1e9 + 7; int T, N; int A[maxn], dp[maxn], c[maxn]; int main() { scanf("%d", &T); while(T --) { scanf("%d", &N); for(int i = 0; i < N; i ++) scanf("%d", &A[i]), dp[i] = 1, c[i] = 1; for(int i = 0; i < N; i ++) { for(int j = 0; j < i; j ++) { if(A[i] <= A[j]) continue; if(dp[j] + 1 == dp[i]) { c[i] = (c[i] + c[j]) % mod; } else if(dp[j] + 1 > dp[i]) { dp[i] = dp[j] + 1; c[i] = c[j]; } } } int ans1 = -1, ans2; for(int i = 0; i < N; i ++) { if(dp[i] > ans1) { ans1 = dp[i]; ans2 = c[i]; } else if(dp[i] == ans1) { ans2 = (ans2 + c[i]) % mod; } } printf("%d %d\n", ans1, ans2); } return 0; } close
D. Football Cup
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; int main() { int T; scanf("%d", &T); while(T--) { int x, y; scanf("%d%d", &x, &y); if(x == y) { printf("Iskandar\n"); } else if(x > y) { printf("Bashar\n"); } else { printf("Hamada\n"); } } return 0; }
E. Adnan and the Burned drivers
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 10; const long long mod = 1e9 + 7; long long base[2] = {131LL, 313LL}; long long b[2][maxn]; char str[2][maxn]; int T, n, m; long long s[2][2][4 * maxn]; void pushUp(int t, int rt) { for(int i = 0; i < 2; i ++) { s[t][i][rt] = (s[t][i][2 * rt] + s[t][i][2 * rt + 1]) % mod; } } void update(int t, int pos, long long dealta, int l, int r, int rt) { if(l == r) { for(int i = 0; i < 2; i ++) { s[t][i][rt] = (s[t][i][rt] + (b[i][pos] * dealta % mod)) % mod; } return; } int mid = (l + r) / 2; if(pos <= mid) update(t, pos, dealta, l, mid, 2 * rt); else update(t, pos, dealta, mid + 1, r, 2 * rt + 1); pushUp(t, rt); } pair<long long, long long> sum(int t, int L, int R, int l, int r, int rt) { if(L <= l && r <= R) { return make_pair(s[t][0][rt], s[t][1][rt]); } int mid = (l + r) / 2; pair<long long, long long> left = make_pair(0LL, 0LL); pair<long long, long long> right = make_pair(0LL, 0LL); if(L <= mid) left = sum(t, L, R, l, mid, 2 * rt); if(R > mid) right = sum(t, L, R, mid + 1, r, 2 * rt + 1); return make_pair((left.first + right.first) % mod, (left.second + right.second) % mod); } void op1(int pos, char sign) { int pos0 = pos; int pos1 = n - pos + 1; if(str[0][pos0] == sign) { return; } long long delta = (sign - str[0][pos0] + mod) % mod; update(0, pos0, delta, 1, n, 1); update(1, pos1, delta, 1, n, 1); str[0][pos0] = sign; str[1][pos1] = sign; } void op2(int L, int R) { int L0 = L, R0 = R; int L1 = n - R + 1, R1 = n - L + 1; pair<long long, long long> pi0 = sum(0, L0, R0, 1, n, 1); pair<long long, long long> pi1 = sum(1, L1, R1, 1, n, 1); if(L0 <= L1) { pi0.first = pi0.first * b[0][L1 - L0] % mod; pi0.second = pi0.second * b[1][L1 - L0] % mod; } else { pi1.first = pi1.first * b[0][L0 - L1] % mod; pi1.second = pi1.second * b[1][L0 - L1] % mod; } if(pi0 == pi1) { printf("Adnan Wins\n"); } else { printf("ARCNCD!\n"); } } int main() { b[0][0] = 1LL; b[1][0] = 1LL; for(int i = 1; i < maxn; i ++) { b[0][i] = b[0][i - 1] * base[0] % mod; b[1][i] = b[1][i - 1] * base[1] % mod; } scanf("%d", &T); while(T --) { scanf("%d%d", &n, &m); memset(s, 0, sizeof s); scanf("%s", str[0] + 1); for(int i = 1; i <= n; i ++) { str[1][i] = str[0][n - i + 1]; } /* for(int i = 1; i <= n; i ++) { printf("%c", str[0][i]); } printf("\n"); for(int i = 1; i <= n; i ++) { printf("%c", str[1][i]); } */ for(int t = 0; t < 2; t ++) { for(int i = 1; i <= n; i ++) { update(t, i, (long long)(str[t][i] - 'a' + 1), 1, n, 1); } } while(m --) { int tp; scanf("%d", &tp); if(tp == 1) { int pos; char sign[5]; scanf("%d%s", &pos, sign); op1(pos, sign[0]); } else { int L, R; scanf("%d%d", &L, &R); op2(L, R); } } } return 0; }
F. Research projects
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; int main() { int T; scanf("%d", &T); while(T--) { long long n, k; scanf("%lld%lld", &n, &k); n = n - k; if(n == 0) { printf("0\n"); continue; } long long ans = n / 6LL; if(n % 6LL != 0) ans ++; printf("%lld\n", ans); } return 0; }
G. Ali and the Breakfast
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; const double eps = 1e-8; const double pi = acos(-1.0); int T, n; double V, L, R; int limit = 30; double length(double x) { double y = x * pi / 180.0; return V * sin(y) * V * cos(y) / 5.0; } double A(double L1, double R1, double L2, double R2) { if(R1 <= L2 || R2 <= L1) return 0.0; if((L1 >= L2 && R1 <= R2) || (L2 >= L1 && R2 <= R1)) return min((R1 - L1), (R2 - L2)); return (min(R1, R2) - max(L1, L2)); } int main() { scanf("%d", &T); while(T --) { scanf("%d%lf%lf%lf", &n, &V, &L, &R); for(int i = 1; i <= n; i ++) { double x, y; scanf("%lf%lf", &x, &y); if(fabs(R - L) <= eps) { double s = length(L); if(x <= s && s <= y) { printf("1.0000\n"); } else { printf("0.0000\n"); } continue; } double left, right; int cou; // [0, 45] left = 0.0, right = 45.0; double pos1 = -1.0; cou = limit; while(cou --) { double m = (left + right) / 2.0; double s = length(m); if(x <= s && s <= y) { pos1 = m; right = m; } else if(s > y) { right = m; } else { left = m; } } // printf("pos1 end %.10f\n", pos1); left = 0.0, right = 45.0; double pos2 = -1.0; cou = limit; while(cou --) { double m = (left + right) / 2.0; double s = length(m); if(x <= s && s <= y) { pos2 = m; left = m; } else if(s > y) { right = m; } else { left = m; } } // printf("pos2 end %.10f\n", pos2); // [45, 90] left = 45.0, right = 90.0; double pos3 = -1.0; cou = limit; while(cou --) { double m = (left + right) / 2.0; double s = length(m); if(x <= s && s <= y) { pos3 = m; right = m; } else if(s > y) { left = m; } else { right = m; } } // printf("pos3 end %.10f\n", pos3); left = 45.0, right = 90.0; double pos4 = -1.0; cou = limit; while(cou --) { double m = (left + right) / 2.0; double s = length(m); if(x <= s && s <= y) { pos4 = m; left = m; } else if(s > y) { left = m; } else { right = m; } } // printf("pos4 end %.10f\n", pos4); double p = 0.0; if(pos1 >= 0) { p += A(L, R, pos1, pos2); } if(pos3 >= 0) { p += A(L, R, pos3, pos4); } printf("%.4f\n", p / (R - L)); } } return 0; }
H. Mr. Hamra and his quantum particles
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 10; int T, N, M, Q; int f[maxn]; void init() { for(int i = 1; i <= N; i ++) f[i] = i; } int Find(int x) { if(f[x] != x) f[x] = Find(f[x]); return f[x]; } void Merge(int x, int y) { int fx = Find(x); int fy = Find(y); if(fx != fy) { f[fx] = fy; } } int main() { scanf("%d", &T); while(T --) { string ans = ""; scanf("%d%d%d", &N, &M, &Q); init(); while(M --) { int st, en; scanf("%d%d", &st, &en); Merge(st, en); } while(Q --) { int qx, qy; scanf("%d%d", &qx, &qy); if(Find(qx) == Find(qy)) ans += '1'; else ans += '0'; } cout << ans << endl; } return 0; }
J. Bashar and daylight saving time
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> const int maxn = 2e5 + 10; int T, n, m; int c[maxn], x[maxn]; int f(int a, int b) { b = b % n; b = (b + n) % n; a --; a = (a + b) % n; a ++; return a; } void add(int L, int R) { //printf("[%d, %d]\n", L, R); c[L] ++; c[R + 1] --; } int main() { scanf("%d", &T); while(T --) { memset(c, 0, sizeof c); scanf("%d%d", &n, &m); for(int i = 1; i <= m; i ++) { scanf("%d", &x[i]); } for(int i = 1; i <= m; i ++) { int y; scanf("%d", &y); if(y == 0) add(x[i], x[i]); else if(abs(y) == n) { add(1, n); add(x[i], x[i]); } else if(abs(y) == n - 1) { add(1, n); } else { int e = f(x[i], y); if(y > 0) { if(e >= x[i]) add(x[i], e); else { add(x[i], n); add(1, e); } } else { if(e <= x[i]) add(e, x[i]); else { add(1, x[i]); add(e, n); } } } } for(int i = 1; i <= n + 1; i ++) { c[i] = c[i] + c[i - 1]; } int ans1 = 0, ans2 = 0; for(int i = 1; i <= n; i ++) { if(c[i] > ans1) { ans1 = c[i]; ans2 = i; } } printf("%d %d\n", ans2, ans1); } return 0; }
K. Masaoud LOVES PIZZAS
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 10; int T, N; long long X; long long a[maxn], sum[maxn]; bool check(int st, int en) { long long ans = sum[en] - sum[st - 1]; if(ans < X) return true; return false; } int main() { scanf("%d", &T); while(T --) { scanf("%d%lld", &N, &X); memset(sum, 0, sizeof(sum)); for(int i = 1; i <= N; i ++) { scanf("%lld", &a[i]); if(i == 1) sum[i] = a[i]; else sum[i] =sum[i - 1] + a[i]; } long long ans = 0; for(int i = 1; i <= N; i ++) { int l = i, r = N, mid, p = 0; while(l <= r) { mid = (l + r) / 2; if(check(i, mid)) { l = mid + 1; p = mid; } else r = mid - 1; } ans = ans + max(0, (p - i + 1)); } printf("%lld\n", ans); } return 0; }
L. Chemistry Exam
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; int main() { int T; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); for(int i = 1; i <= n; i ++) { int x; scanf("%d", &x); int ans = 0; while(x > 0) { ans = ans + x % 2; x = x / 2; } printf("%d", ans); if(i < n) printf(" "); else printf("\n"); } } return 0; }
M. NCD Salary
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; int T; int B1, P1, B2, P2; int main() { scanf("%d", &T); while(T --) { scanf("%d%d%d%d", &B1, &P1, &B2, &P2); if(B1 == 0 || B2 == 0) { if(B1 == B2) printf("Lazy\n"); else if(B1 > B2) printf("HaHa\n"); else printf("Congrats\n"); continue; } double num1 = 1.0 * P1 * log(1.0 * B1); double num2 = 1.0 * P2 * log(1.0 * B2); if(fabs(num1 - num2) <= 1e-7) printf("Lazy\n"); else if(num1 > num2) printf("HaHa\n"); else printf("Congrats\n"); } return 0; }