[关闭]
@2368860385 2018-08-31T08:30:34.000000Z 字数 3146 阅读 515

六校联考day1——2018.8.29

比赛总结

备注:放假了,未参加,后来做了一下。


T1

在衢州时的ACM,做过。

T2

求多少个[l,r],满足
转化




即对于每个r,求多少个l满足上式。
就是在[1,r-1]里多少个T[i] >= T[r],对于1~r这样的区间没法统计,所以特判一下。
离散化后树状数组维护。

开longlong。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<cctype>
  6. #include<cmath>
  7. #include<set>
  8. #include<map>
  9. #include<queue>
  10. #include<vector>
  11. using namespace std;
  12. typedef long long LL;
  13. inline int read() {
  14. int x = 0, f = 1; char ch = getchar(); for (; !isdigit(ch); ch=getchar()) if (ch=='-') f = -1;
  15. for (; isdigit(ch); ch=getchar()) x = x * 10 + ch - '0'; return x * f;
  16. }
  17. const int N = 50010;
  18. LL s[N], T[N], Num[N];
  19. int pos[N];
  20. struct BIT{
  21. int n;int sum[N];
  22. void update(int p,int x) {
  23. for (; p<=n; p+=(p&(-p))) sum[p] += x;
  24. }
  25. int query(int p) {
  26. int ans = 0;
  27. for (; p; p-=(p&(-p))) ans += sum[p];
  28. return ans;
  29. }
  30. void Clear() {
  31. memset(sum, 0, sizeof(sum));
  32. }
  33. int Ask(int l,int r) {
  34. return query(r) - query(l - 1);
  35. }
  36. }bit;
  37. int find(int L,int R,LL x) {
  38. int ans = 0;
  39. while (L <= R) {
  40. int mid = (L + R) >> 1;
  41. if (Num[mid] >= x) ans = mid, R = mid - 1;
  42. else L = mid + 1;
  43. }
  44. return ans;
  45. }
  46. void solve(int n,int k) {
  47. for (int i=1; i<=n; ++i) T[i] = s[i] - 1ll * k * i, Num[i] = T[i];
  48. sort(Num + 1, Num + n + 1);
  49. int cnt = 1;
  50. for (int i=2; i<=n; ++i) if (Num[i] != Num[cnt]) Num[++cnt] = Num[i];
  51. for (int i=1; i<=n; ++i) pos[i] = find(1, cnt, T[i]);
  52. bit.n = cnt;
  53. bit.Clear();
  54. LL Ans = 0;
  55. for (int i=1; i<=n; ++i) {
  56. Ans += (Num[pos[i]] <= 0);
  57. Ans += bit.Ask(pos[i], cnt);
  58. bit.update(pos[i], 1);
  59. }
  60. cout << Ans << "\n";
  61. }
  62. int main() {
  63. freopen("h.in","r",stdin);
  64. freopen("h.out","w",stdout);
  65. int n = read();
  66. for (int i=1; i<=n; ++i)
  67. s[i] = s[i - 1] + read();
  68. int m = read();
  69. while (m --) {
  70. int k = read();
  71. solve(n, k);
  72. }
  73. return 0;
  74. }

T3

很重要一点,原图中两个点之间只有一条边。
所以对于u->v->w,如果这两条属于一个人,那么只有u->w属于个人的时候是正确的。如果对于一个人的点全正确,那么就是合法的,否则是不合法的。
枚举三个点,这样是
正难则反,那么知道了一个人如果没有不正确的情况,也就是合法的,否则不合法的。
正确的情况知道了,就是u->w一定属于同一个人,那么不正确的情况:
1、u->w属于另一个人
2、w->u这条边存在,不管属于谁,都说明了u->w这条边不存在。
2就是原图中有环,1就是将一个人的边取反后图中有环。
如果原图与将一个人取反后的图都没有环,那么说明答案为YE5,否则答案为N0。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<cctype>
  6. #include<cmath>
  7. #include<set>
  8. #include<map>
  9. #include<queue>
  10. #include<vector>
  11. using namespace std;
  12. typedef long long LL;
  13. inline int read() {
  14. int x = 0, f = 1; char ch = getchar(); for (; !isdigit(ch); ch=getchar()) if (ch=='-') f = -1;
  15. for (; isdigit(ch); ch=getchar()) x = x * 10 + ch - '0'; return x * f;
  16. }
  17. const int N = 3010;
  18. int deg[N], q[N];
  19. bool vis[N];
  20. char s[N][N];
  21. vector<int> e[N];
  22. int n;
  23. void add_edge(int u,int v) {
  24. deg[v] ++;
  25. e[u].push_back(v);
  26. }
  27. void init() {
  28. memset(deg, 0, sizeof(deg));
  29. for (int i=1; i<=n; ++i) {
  30. e[i].clear();
  31. deg[i] = 0;
  32. q[i] = 0;
  33. vis[i] = false;
  34. }
  35. }
  36. void build(int flag) {
  37. for (int i=1; i<=n; ++i) {
  38. for (int j=1; j<=n; ++j) {
  39. if (s[i][j] == 'H') add_edge(i, j);
  40. if (s[i][j] == 'W') flag ? add_edge(i, j) : add_edge(j, i);
  41. }
  42. }
  43. }
  44. bool topo() {
  45. int L = 1, R = 0;
  46. for (int i=1; i<=n; ++i)
  47. if (!deg[i]) q[++R] = i;
  48. while (L <= R) {
  49. int u = q[L++];
  50. vis[u] = true;
  51. for (int sz=e[u].size(),i=0; i<sz; ++i) {
  52. int v = e[u][i];
  53. if (vis[v]) return false; // 判环
  54. deg[v] --;
  55. if (!deg[v]) q[++R] = v;
  56. }
  57. }
  58. for (int i=1; i<=n; ++i) // 可能有一个封闭的环,没有入度为0的点。
  59. if (!vis[i]) return false;
  60. return true;
  61. }
  62. int main() {
  63. freopen("p.in","r",stdin);
  64. freopen("p.out","w",stdout);
  65. int T = read();
  66. while (T--) {
  67. n = read();
  68. for (int i=1; i<=n; ++i) scanf("%s",s[i]+1);
  69. init(); build(1);
  70. if (!topo()) { puts("N0"); continue; }
  71. init(); build(0);
  72. if (!topo()) { puts("N0"); continue; }
  73. puts("YE5");
  74. }
  75. return 0;
  76. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注