2020.7.13 解题报告

2020.7.13


\[\text{Happy Birthday!} \]

\[\text{to Luckyblock} \]


答题情况

总成绩 : 180 , 排名 : 1 / 8
T1 : 60 T2 : 20 T3 : 100

各题目分析

题目 1 :
预估成绩 : 100 实际成绩 : 60 考试用时 : 2:30 ~ 2:55

一眼秒,直接写标算。
拍了1w 组数据。
最后犹豫开不开 long long,偷懒没开。
哭了。

题目 2 :
预估成绩 : 20 实际成绩 : 20 考试用时 : 4:30 ~ 5:20

神题,写了20。

题目 3 :
预估成绩 : 100 实际成绩 : 100 考试用时 : 3:00 ~ 4:00

一眼秒,直接写标算。
拍了1w 组数据。


题目解析

T1

预处理 f 和 g。排序离散后相当于 逆序对问题。
用线段树或者树状数组统计答案即可。


T2

对于 20%的数据:暴力 Dfs 每次都在哪里升级。
对于 30-40%的数据:由于 R 为 0,直接二分答案,枚举判断。
对于 50-60%的数据:二分答案,一个显然的性质是如果[1,x-1]的区间都已经满足条件,那么这
一次升级放在 x+R-1 点一定答案最优。问题变成区间加,单点查询,用线段树或树状数组能方便
的查询。
对于 70%-100%的数据:发现这个问题和“滑窗问题”类似。考虑用一个单调队列来维护当前区间
被升级了多少次。


T3

离线。对询问排序,从小到大向一个空图加边。加边后用一个并查集维护连通性。
又因为加边后答案是单调递增的,能很方便的维护最大值。


代码实现

T1 :

考场代码

//
/*
By:Luckyblock
实际上是个逆序对 问题
树状数组水一水 
*/
#include <cstdio>
#include <ctype.h>
#include <algorithm>
#define lowbit(x) (x&-x)
#define ll long long
const int kMaxn = 3e5 + 10;
//=============================================================
struct Data {
  ll val, id;
  int pos;
} data[kMaxn];
struct Tom {
  ll a, f, g, id;
} a[kMaxn];
int n, k, maxx, ans, t[kMaxn];
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
  return f * w;
}
void GetMax(int &fir, int sec) {
  if (sec > fir) fir = sec;
}
void GetMin(int &fir, int sec) {
  if (sec < fir) fir = sec;
}
ll qmul(ll x, ll y) {
  ll ret = 1;
  while (y) {
    if (y & 1) ret = ret * x % k;
    x = x * x % k, y >>= 1;
  }
  return ret;
}
bool Compare(Data fir, Data sec) {
  return fir.val < sec.val;
}
void Modify(int pos, int val) {
  for (int i = pos; i <= maxx; i += lowbit(i)) t[i] += val;
}
int Query(int pos) {
  int ret = 0;
  for (int i = pos; i; i -= lowbit(i)) 
    ret += t[i];
  return ret;
}
//=============================================================
int main() {
  freopen("Calc.in", "r", stdin);
  freopen("Calc.out", "w", stdout);
  n = read(), k = read();
  for (int i = 1; i <= n; ++ i) {
    a[i].a = (ll) read(); 
    a[i].f = qmul(i, a[i].a);
    a[i].g = qmul(a[i].a, i);
    data[i] = (Data) {a[i].a, i, 1};
    data[n + i] = (Data) {a[i].f, i, 2};
    data[2 * n + i] = (Data) {a[i].g, i, 3};
  }
  std :: sort(data + 1, data + 3 * n + 1, Compare);
  data[0].val = - 114514;
  for (int i = 1; i <= 3 * n; ++ i) {
    if (data[i].val > data[i - 1].val) maxx ++;
    if (data[i].pos == 1) a[data[i].id].a = maxx;
    if (data[i].pos == 2) a[data[i].id].f = maxx;
    if (data[i].pos == 3) a[data[i].id].g = maxx;
  }
  
  for (int i = 1; i <= n; ++ i) {
    ans += Query(maxx) - Query(a[i].g);
    Modify(a[i].f, 1);
  }
  printf("%d\n", ans);
  return 0;
}
//暴力 
/*
#include <cstdio>
#include <ctype.h>
#include <algorithm>
#define lowbit(x) (x&-x)
#define ll long long
const int kMaxn = 1e5 + 10;
//=============================================================
struct Tom {
  ll a, f, g, id;
} a[kMaxn];
int n, k, ans;
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
  return f * w;
}
void GetMax(int &fir, int sec) {
  if (sec > fir) fir = sec;
}
void GetMin(int &fir, int sec) {
  if (sec < fir) fir = sec;
}
ll qmul(ll x, ll y) {
  ll ret = 1;
  while (y) {
    if (y & 1) ret = ret * x % k;
    x = x * x % k, y >>= 1;
  }
  return ret;
}
//=============================================================
int main() {
  freopen("Calc.in", "r", stdin);
  freopen("2.out", "w", stdout);
  n = read(), k = read();
  for (int i = 1; i <= n; ++ i) {
    a[i].a = (ll) read(); 
    a[i].f = qmul(i, a[i].a);
    a[i].g = qmul(a[i].a, i);
  }
  
  for (int l = 1; l <= n; ++ l) {
    for (int r = l + 1; r <= n; ++ r) {
      if (a[l].f > a[r].g) ans ++;
    }
  }
  printf("%d\n", ans);
  return 0;
}
*/
//数据生成器
/*
#include <bits/stdc++.h>
#include <ctype.h>
#include <algorithm>
#define ll long long
const int kMaxn = 1e4;
const int kMaxk = 1e9;
//=============================================================
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
  return f * w;
}
void GetMax(int &fir, int sec) {
  if (sec > fir) fir = sec;
}
void GetMin(int &fir, int sec) {
  if (sec < fir) fir = sec;
}
//=============================================================
int main() {
  freopen("Calc.in", "w", stdout);
  srand(time(0));
  int n = rand() % kMaxn + 1, k = kMaxk;
  printf("%d %d\n", n, k);
  for (int i = 1; i <= n; ++ i) {
    printf("%d ", rand() % kMaxk + 1);
  }
  return 0;
}
*/ 
//checker
/*
#include <bits/stdc++.h>
#include <ctype.h>
#include <algorithm>
#define ll long long
//=============================================================
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
  return f * w;
}
void GetMax(int &fir, int sec) {
  if (sec > fir) fir = sec;
}
void GetMin(int &fir, int sec) {
  if (sec < fir) fir = sec;
}
//=============================================================
int main() {
  for (int i = 1; ; ++ i) {
    system("datamaker.exe");
    system("Calc.exe");
    system("Calcbaoli.exe");
    printf("%d ", i);
    if (system("fc Calc.out 2.out")) break;
  }
  return 0;
}
*/

T2:

考场代码

//
/*
By:Luckyblock
神题
*/
#include <cstdio>
#include <ctype.h>
#include <algorithm>
#define ll long long
const int kMaxn = 5e5 + 10;
//=============================================================
ll n, r, k, a[kMaxn];
ll maxx, cnt[kMaxn], map[kMaxn], delta[kMaxn]; 
//=============================================================
inline ll read() {
  ll f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
  return f * w;
}
void GetMax(int &fir, int sec) {
  if (sec > fir) fir = sec;
}
void GetMin(int &fir, int sec) {
  if (sec < fir) fir = sec;
}
//=============================================================
int main() {
  freopen("Game.in", "r", stdin);
  freopen("Game.out", "w", stdout);
  n = read(), r = read(), k = read();
  for (int i = 1; i <= n; ++ i) a[i] = read();
  std :: sort(a + 1, a + n + 1);
  for (int i = 1; i <= n; ++ i) {
    if (a[i] > a[i - 1]) {
      delta[maxx] = a[i] - a[i - 1];
      map[++ maxx] = a[i];
    }
    cnt[maxx] ++;
  }
  for (int i = 1; i < maxx; ++ i) {
    ll need = cnt[i] * delta[i];
    if (need > k) {
      printf("%lld", map[i] + (k / cnt[i]));
      return 0;
    }
    if (need == k) {
      printf("%lld", map[i]);
      return 0;
    }
    k -= need;
    cnt[i + 1] += cnt[i];
  }
  printf("%lld", map[maxx] + (k / n));
  return 0;
}
/*
5 0 100
1 200 4 3 50
*/

T3:

考场代码

//
/*
By:Luckyblock
并查集水一水
发现暴力写挂啦 
最后拍上了
*/
#include <cstdio>
#include <ctype.h>
#include <algorithm>
#define ll long long
const int kMaxn = 1e5 + 10;
//=============================================================
struct Edge {
  int u, v, w;
} e[kMaxn << 1];
struct Query {
  int q, id;
} q[kMaxn];
int n, m, k, edge_num, id[kMaxn];
int bel[kMaxn];
int nowans, sum[kMaxn], ans[kMaxn];
//============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
  return f * w;
}
void GetMax(int &fir, int sec) {
  if (sec > fir) fir = sec;
}
void GetMin(int &fir, int sec) {
  if (sec < fir) fir = sec;
}
void AddEdge(int u, int v, int w) {
  e[++ edge_num].u = u, e[edge_num].v = v, e[edge_num].w = w;
}
bool CompareEdge(Edge fir, Edge sec) {
  return fir.w < sec.w;
}
bool CompareQuery(Query fir, Query sec) {
  return fir.q < sec.q;
}
int Find(int x) {
  return x == bel[x] ? x : bel[x] = Find(bel[x]);
}
void Unico(int x, int y, int w) {
  int r1 = Find(x), r2 = Find(y);
  bel[r2] = r1;
  sum[r1] += sum[r2] + w;
  GetMax(nowans, sum[r1]);
}
//=============================================================
int main() {
  freopen("Graph.in", "r", stdin);
  freopen("Graph.out", "w", stdout);
  n = read(), m = read(), k = read();
  for (int i = 1; i <= m; ++ i) {
    int u = read(), v = read(), w = read();
    AddEdge(u, v, w);
  }
  for (int i = 1; i <= k; ++ i) {
    q[i].q = read(), q[i].id = i; 
  }
  std :: sort(q + 1, q + k + 1, CompareQuery);
  std :: sort(e + 1, e + edge_num + 1, CompareEdge);
  for (int i = 1; i <= n; ++ i) bel[i] = i;
  
  for (int i = 1, j = 1; i <= k; ++ i) {
    for (; j <= edge_num && e[j].w <= q[i].q; ++ j) {
      int u = e[j].u, v = e[j].v, w = e[j].w;
      if (Find(u) == Find(v)) {
        sum[Find(u)] += w;
        GetMax(nowans, sum[Find(u)]);
      } else {
        Unico(u, v, w);
      }
    }
    ans[q[i].id] = nowans;
  }
  for (int i = 1; i <= k; ++ i) printf("%d\n", ans[i]);
  return 0;
}
//暴力 
/*
#include <cstdio>
#include <ctype.h>
#include <cstring>
#include <algorithm>
#define ll long long
const int kMaxn = 1e5 + 10;
//=============================================================
struct Edge {
  int u, v, w, ne;
} e[kMaxn << 1], e1[kMaxn << 1];
int n, m, k, edge_num, edge_num1, ans, sum[kMaxn], head1[kMaxn];
bool vis[kMaxn], use[kMaxn << 1];
//============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
  return f * w;
}
void GetMax(int &fir, int sec) {
  if (sec > fir) fir = sec;
}
void GetMin(int &fir, int sec) {
  if (sec < fir) fir = sec;
}
void AddEdge(int u, int v, int w) {
  e[++ edge_num].u = u, e[edge_num].v = v, e[edge_num].w = w;
}
void AddEdge1(int u, int v, int w) {
  e1[++ edge_num1].u = u, e1[edge_num1].v = v, e1[edge_num1].w = w;
  e1[edge_num1].ne = head1[u], head1[u] = edge_num1;
}
bool Compare(Edge fir, Edge sec) {
  return fir.w < sec.w;
}
void Dfs(int u, int root) {
  vis[u] = true;
  for (int i = head1[u]; i >= 0; i = e1[i].ne) {
    if (use[i]) continue ;
    sum[root] += e1[i].w;
    use[i] = true;
    use[i ^ 1] = true;
    Dfs(e1[i].v, root);
  }
}
//=============================================================
int main() {
  freopen("Graph.in", "r", stdin);
  freopen("Graphbaoli.out", "w", stdout);
  n = read(), m = read(), k = read();
  for (int i = 1; i <= m; ++ i) {
    int u = read(), v = read(), w = read();
    AddEdge(u, v, w);
  }
  std :: sort(e + 1, e + edge_num + 1, Compare);
  for (int i = 1; i <= k; ++ i) {
    memset(head1, 128, sizeof(head1));
    memset(vis, 0, sizeof(vis));
    memset(use, 0, sizeof(use));
    memset(sum, 0, sizeof(sum));
    ans = 0; edge_num1 = - 1;
    
    int q = read();
    for (int j = 1; j <= edge_num && e[j].w <= q; ++ j) {
      AddEdge1(e[j].u, e[j].v, e[j].w);
      AddEdge1(e[j].v, e[j].u, e[j].w);
    }
    for (int i = 1; i <= n; ++ i) {
      if (vis[i]) continue ;
      Dfs(i, i);
      GetMax(ans, sum[i]);
    }
    printf("%d\n", ans);
  }
  
  return 0;
}
*/ 
//数据生成器
/*
#include <bits/stdc++.h>
#include <ctype.h>
#include <algorithm>
#define ll long long
const int kMaxn = 10000;
const int kMaxw = 1000;
//=============================================================
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
  return f * w;
}
void GetMax(int &fir, int sec) {
  if (sec > fir) fir = sec;
}
void GetMin(int &fir, int sec) {
  if (sec < fir) fir = sec;
}
//=============================================================
int main() {
  freopen("Graph.in", "w", stdout);
  srand(time(0));
  int n = rand() % kMaxn + 1, 
      m = rand() % kMaxn + 1, 
      q = rand() % kMaxn + 1;
  printf("%d %d %d\n", n, m, q);
  for (int i = 1; i <= m; ++ i) {
    int u = rand() % n + 1, w = rand() % kMaxw + 1, v;
    do v = rand() % n + 1;
    while (u == v);
    printf("%d %d %d\n", u, v, w);
  }
  for (int i = 1; i <= q; ++ i) {
    printf("%d\n", rand() % kMaxw + 1);
  }
  return 0;
}
*/ 
//checker
/*
#include <bits/stdc++.h>
#include <ctype.h>
#include <algorithm>
#define ll long long
//=============================================================
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
  return f * w;
}
void GetMax(int &fir, int sec) {
  if (sec > fir) fir = sec;
}
void GetMin(int &fir, int sec) {
  if (sec < fir) fir = sec;
}
//=============================================================
int main() {
  for (int i = 1; ; ++ i) {
    system("datamakerGraph.exe");
    system("Graph.exe");
    system("Graphbaoli.exe");
    printf("%d ", i);
    if (system("fc Graph.out Graphbaoli.out")) break;
  }
  return 0;
}
*/
posted @ 2020-07-13 19:00  Luckyblock  阅读(134)  评论(0编辑  收藏  举报