18/9/21模拟赛

期望得分:100;实际得分:0  qwq

拿到题目第一眼,我去,这不是洛谷原题(仓鼠找Sugar)吗

又多看了几眼,嗯,对,除了是有多组数据外,就是原题

然后码码码。。。。自以为写的很对 qwq

评测结束后。。。为什么我T1没有输出啊啊啊。。。

经某童鞋帮忙,发现

第一次被文件输入输出坑 qwqwq。。。

加上后就A了,白丢100 pts 蓝瘦

思路:树剖分别求LCA,然后判断LCA是否在另一条路径上

不要忘记清空数组!

  1. #include <algorithm>
  2. #include <cstring>
  3. #include <cstdio>
  4. using namespace std;
  5. const int M = ;
  6. int T, n, m, tot;
  7. int to[M << ], net[M << ], head[M];
  8. int deep[M], top[M], dad[M], size[M];
  9.  
  10. void add(int u, int v) {
  11. to[++tot] = v; net[tot] = head[u]; head[u] = tot;
  12. to[++tot] = u; net[tot] = head[v]; head[v] = tot;
  13. }
  14.  
  15. void dfs(int now) {
  16. size[now] = ;
  17. deep[now] = deep[dad[now]] + ;
  18. for (int i = head[now]; i; i = net[i])
  19. if (to[i] != dad[now]) {
  20. dad[to[i]] = now;
  21. dfs(to[i]);
  22. size[now] += size[to[i]];
  23. }
  24. }
  25.  
  26. void dfsl(int now) {
  27. int t = ;
  28. if (!top[now]) top[now] = now;
  29. for (int i = head[now]; i; i = net[i])
  30. if (to[i] != dad[now] && size[to[i]] > size[t])
  31. t = to[i];
  32. if (t) {
  33. top[t] = top[now];
  34. dfsl(t);
  35. }
  36. for (int i = head[now]; i; i = net[i])
  37. if (to[i] != dad[now] && to[i] != t)
  38. dfsl(to[i]);
  39. }
  40.  
  41. int lca(int x, int y) {
  42. while (top[x] != top[y]) {
  43. if (deep[top[x]] < deep[top[y]])
  44. swap(x, y);
  45. x = dad[top[x]];
  46. }
  47. return deep[x] > deep[y] ? y : x;
  48. }
  49.  
  50. void clear() {
  51. tot = ;
  52. memset(to, , sizeof to);
  53. memset(net, , sizeof net);
  54. memset(dad, , sizeof dad);
  55. memset(top, , sizeof top);
  56. memset(head, , sizeof head);
  57. memset(deep, , sizeof deep);
  58. memset(size, , sizeof size);
  59. }
  60.  
  61. int main() {
  62. freopen("railway.in","r",stdin);
  63. freopen("railway.out","w",stdout);
  64. scanf("%d", &T);
  65. for (int q = ; q <= T; ++q) {
  66. if (q != ) clear();
  67. scanf("%d%d", &n, &m);
  68. for (int i = ; i < n; ++i) {
  69. int u, v;
  70. scanf("%d%d", &u, &v);
  71. add(u, v);
  72. }
  73. dfs();
  74. dfsl();
  75. for (int i = ; i <= m; ++i) {
  76. int a, b, c, d;
  77. scanf("%d%d%d%d", &a, &b, &c, &d);
  78. int S = lca(a, b);
  79. int R = lca(c, d);
  80. if (S < R) {
  81. swap(S, R);
  82. swap(a, c);
  83. swap(b, d);
  84. }
  85. if (lca(S, c) == S || lca(S, d) == S) printf("YES\n");
  86. else printf("NO\n");
  87. }
  88. }
  89. fclose(stdin); fclose(stdout);
  90. return ;
  91. }

期望得分:100? 实际得分:20  (那80pts的都TLE了。。。)

思路:线段树维护区间的最大最小值,然后枚举每一个区间求解

事实证明,我真的不会算时间复杂度 qwq

  1. #include <algorithm>
  2. #include <cstring>
  3. #include <cstdio>
  4.  
  5. #ifdef WIN32
  6. #define LL "%I64d\n"
  7. #else
  8. #define LL "%lld\n"
  9. #endif
  10.  
  11. using namespace std;
  12. typedef long long Ll;
  13. const int M = ;
  14. int n, m;
  15. Ll ans;
  16. int ll[M << ], rr[M << ];
  17. int maxn[M << ], minn[M << ];
  18.  
  19. void update(int now) {
  20. maxn[now] = max(maxn[now << ], maxn[now << | ]);
  21. minn[now] = min(minn[now << ], minn[now << | ]);
  22. }
  23.  
  24. void build(int now, int l, int r) {
  25. ll[now] = l; rr[now] = r;
  26. if (l == r) {
  27. scanf("%d", &maxn[now]);
  28. minn[now] = maxn[now];
  29. return ;
  30. }
  31. int mid = (l + r) >> ;
  32. build(now << , l, mid);
  33. build(now << | , mid + , r);
  34. update(now);
  35. }
  36.  
  37. int query(int now, int l, int r) {
  38. if (ll[now] == l && rr[now] == r)
  39. return maxn[now];
  40. int mid = (ll[now] + rr[now]) >> ;
  41. if (l <= mid && mid < r) return max(query(now << , l, mid), query(now << | , mid + , r));
  42. else if (r <= mid) return query(now << , l, r);
  43. else return query(now << | , l, r);
  44. }
  45.  
  46. int found(int now, int l, int r) {
  47. if (ll[now] == l && rr[now] == r)
  48. return minn[now];
  49. int mid = (ll[now] + rr[now]) >> ;
  50. if (l <= mid && mid < r) return min(found(now << , l, mid), found(now << | , mid + , r));
  51. else if (r <= mid) return found(now << , l, r);
  52. else return found(now << | , l, r);
  53. }
  54.  
  55. void clear() {
  56. ans = ;
  57. memset(ll, , sizeof ll);
  58. memset(rr, , sizeof rr);
  59. memset(maxn, , sizeof maxn);
  60. memset(minn, , sizeof minn);
  61. }
  62.  
  63. int main() {
  64. freopen("count.in","r",stdin);
  65. freopen("count.out","w",stdout);
  66. scanf("%d", &m);
  67. for (int q = ; q <= m; ++q) {
  68. if (q != ) clear();
  69. scanf("%d", &n);
  70. build(, , n);
  71. for (int i = ; i <= n; ++i)
  72. for (int j = i + ; j <= n; ++j)
  73. ans += (query(, i, j) - found(, i, j));
  74. printf(LL, ans);
  75. }
  76. fclose(stdin); fclose(stdout);
  77. return ;
  78. }

考场20pts代码

正解:因为排列是随机的,所以从每个点向后可能的差值最多 2logn 个,所以答案最多只可能有nlogn 种,用单调队列找出来统计即可

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<cstdlib>
  7. using namespace std;
  8. typedef long long ll;
  9. typedef long double ld;
  10. typedef pair<int,int> pr;
  11. const double pi=acos(-);
  12. #define rep(i,a,n) for(int i=a;i<=n;i++)
  13. #define per(i,n,a) for(int i=n;i>=a;i--)
  14. #define Rep(i,u) for(int i=head[u];i;i=Next[i])
  15. #define clr(a) memset(a,0,sizeof a)
  16. #define pb push_back
  17. #define mp make_pair
  18. #define putk() putchar(' ')
  19. ld eps=1e-;
  20. ll pp=;
  21. ll mo(ll a,ll pp){if(a>= && a<pp)return a;a%=pp;if(a<)a+=pp;return a;}
  22. ll powmod(ll a,ll b,ll pp){ll ans=;for(;b;b>>=,a=mo(a*a,pp))if(b&)ans=mo(ans*a,pp);return ans;}
  23. ll gcd(ll a,ll b){return (!b)?a:gcd(b,a%b);}
  24. ll read(){
  25. ll ans=;
  26. char last=' ',ch=getchar();
  27. while(ch<'' || ch>'')last=ch,ch=getchar();
  28. while(ch>='' && ch<='')ans=ans*+ch-'',ch=getchar();
  29. if(last=='-')ans=-ans;
  30. return ans;
  31. }
  32. void put(ll a){
  33. if(a<)putchar('-'),a=-a;
  34. int top=,q[];
  35. while(a)q[++top]=a%,a/=;
  36. top=max(top,);
  37. while(top--)putchar(''+q[top+]);
  38. }
  39. //head
  40. #define N 210000
  41. int n,a[N],f1[N],f2[N],q[N];
  42. ll s[N];
  43. void solved(){
  44. n=read();
  45. rep(i,,n)a[i]=read();
  46. a[n+]=n+;
  47. q[]=n+;
  48. int t=;
  49. per(i,n,){
  50. while(t && a[q[t]]<=a[i])--t;
  51. f1[i]=q[t];
  52. q[++t]=i;
  53. }
  54. a[n+]=;
  55. q[]=n+;
  56. t=;
  57. per(i,n,){
  58. while(t && a[q[t]]>=a[i])--t;
  59. f2[i]=q[t];
  60. q[++t]=i;
  61. }
  62. rep(i,,n)s[i]=;
  63. rep(i,,n){
  64. int z1=i,z2=i;
  65. while(z1!=n+ && z2!=n+){
  66. if(f1[z1]<=f2[z2]){
  67. int tt=max(z1,z2),zz=a[z1]-a[z2];
  68. z1=f1[z1];
  69. s[zz]+=max(z1,z2)-tt;
  70. }
  71. else{
  72. int tt=max(z1,z2),zz=a[z1]-a[z2];
  73. z2=f2[z2];
  74. s[zz]+=max(z1,z2)-tt;
  75. }
  76. }
  77. }
  78. ll ans=;
  79. rep(i,,n-)
  80. ans+=s[i]*i;
  81. cout<<ans<<endl;
  82. }
  83. int main(){
  84. freopen("count.in","r",stdin);
  85. freopen("count.out","w",stdout);
  86. int T=read();
  87. while(T--){
  88. solved();
  89. }
  90. return ;
  91. }

正解

比题解更好的做法  ——By lgj

分别求所有区间的最大值和、最小值和

用单调栈维护,用sum记录已经求过的区间的最大值的和

求最小值时,可将所有的数转为负数,重新跑一遍即可

最后将两次求出的值相加即可

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<algorithm>
  4. #include<iostream>
  5. #define LL long long
  6. using namespace std;
  7. const LL MAXN = 1e5 + ;
  8. inline LL read() {
  9. char c = getchar(); LL x = , f = ;
  10. while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
  11. while(c >= '' && c <= '') x = x * + c - '', c = getchar();
  12. return x * f;
  13. }
  14. LL T, N;
  15. LL a[MAXN], q[MAXN];
  16. LL solve() {
  17. LL h = , t = , ans = , sum = ;
  18. for(LL i = ; i <= N; i++) {
  19. while(h <= t && a[i] > a[q[t]]) sum -= a[q[t]] * (q[t] - q[t - ]), t--;
  20. q[++t] = i;
  21. ans += a[i] * (q[t] - q[t - ]) + sum;
  22. sum += a[i] * (q[t] - q[t - ]);
  23. }
  24. return ans;
  25. }
  26. int main() {
  27. freopen("count.in", "r", stdin);
  28. freopen("count.out", "w", stdout);
  29. T = read();
  30. while(T--) {
  31. N = read();
  32. for(LL i = ; i <= N; i++) a[i] = read();
  33. LL ans = solve();
  34. for(LL i = ; i <= N; i++) a[i] = -a[i];
  35. LL ans2 = solve();
  36. cout << ans + ans2 << endl;
  37. }
  38. return ;
  39. }

% lgj dalao

期望得分:0;实际得分:0

一开始以为样例错了,死活推不出来

前一个小时做了前两题,剩下的时间大部分就在推样例发呆中度过了

最后半小时才发现读错题 qwq

然而暴力也写不完了。。。

正解:对于每一条边统计有多少个区间跨过这条边即可

统计这一问题的对偶问题,有多少个区间没跨过会更方便

使用启发式合并+并查集统计子树内的,使用启发式合并+set 统计子树外的

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<cstdlib>
  7. #include<set>
  8. #include<ctime>
  9. using namespace std;
  10. typedef long long ll;
  11. typedef long double ld;
  12. typedef pair<int,int> pr;
  13. const double pi=acos(-);
  14. #define rep(i,a,n) for(int i=a;i<=n;i++)
  15. #define per(i,n,a) for(int i=n;i>=a;i--)
  16. #define Rep(i,u) for(int i=head[u];i;i=Next[i])
  17. #define clr(a) memset(a,0,sizeof a)
  18. #define pb push_back
  19. #define mp make_pair
  20. ld eps=1e-;
  21. ll pp=;
  22. ll mo(ll a,ll pp){if(a>= && a<pp)return a;a%=pp;if(a<)a+=pp;return a;}
  23. ll powmod(ll a,ll b,ll pp){ll ans=;for(;b;b>>=,a=mo(a*a,pp))if(b&)ans=mo(ans*a,pp);return ans;}
  24. ll read(){
  25. ll ans=;
  26. char last=' ',ch=getchar();
  27. while(ch<'' || ch>'')last=ch,ch=getchar();
  28. while(ch>='' && ch<='')ans=ans*+ch-'',ch=getchar();
  29. if(last=='-')ans=-ans;
  30. return ans;
  31. }
  32. //head
  33. #define N 110000
  34. int head[N],Next[N*],v[N*],num,fa[N],son[N],sum[N],n,s[N],Fa[N];
  35. ll ans=,Sum,Sum2;
  36. bool vis[N];
  37. set<int>Q;
  38. set<int>::iterator it,it1,it2;
  39. int find(int x){
  40. if(x==Fa[x])return x;
  41. return Fa[x]=find(Fa[x]);
  42. }
  43. void add(int x,int y){
  44. v[++num]=y;Next[num]=head[x];head[x]=num;
  45. }
  46. void dfs1(int u){
  47. sum[u]=;son[u]=;
  48. for(int i=head[u];i;i=Next[i])
  49. if(v[i]!=fa[u]){
  50. fa[v[i]]=u;
  51. dfs1(v[i]);
  52. sum[u]+=sum[v[i]];
  53. if(!son[u] || sum[v[i]]>sum[son[u]])son[u]=v[i];
  54. }
  55. }
  56. ll cal(ll n){
  57. return n*(n-)/;
  58. }
  59. void Add(int u){
  60. Q.insert(u);
  61. it=Q.find(u);
  62. it1=it2=it;
  63. it1--;it2++;
  64. Sum2-=cal((*it2)-(*it1)-);
  65. Sum2+=cal((*it)-(*it1)-)+cal((*it2)-(*it)-);
  66. vis[u]=;
  67. if(vis[u-]){
  68. int fx=find(u-),fy=find(u);
  69. Sum+=(ll)s[fx]*s[fy];
  70. Fa[fx]=fy;
  71. s[fy]+=s[fx];
  72. }
  73. if(vis[u+]){
  74. int fx=find(u+),fy=find(u);
  75. Sum+=(ll)s[fx]*s[fy];
  76. Fa[fx]=fy;
  77. s[fy]+=s[fx];
  78. }
  79. }
  80. void bfs(int u){
  81. Add(u);
  82. for(int i=head[u];i;i=Next[i])
  83. if(v[i]!=fa[u])bfs(v[i]);
  84. }
  85. void clear(int u){
  86. s[u]=;vis[u]=;Fa[u]=u;
  87. for(int i=head[u];i;i=Next[i])
  88. if(v[i]!=fa[u])clear(v[i]);
  89. }
  90. void dfs2(int u){
  91. for(int i=head[u];i;i=Next[i])
  92. if(v[i]!=fa[u] && v[i]!=son[u]){
  93. dfs2(v[i]);
  94. clear(v[i]);
  95. Sum=;
  96. Q.clear();
  97. Q.insert();
  98. Q.insert(n+);
  99. Sum2=(ll)(n-)*n/;
  100. }
  101.  
  102. if(son[u])dfs2(son[u]);
  103. for(int i=head[u];i;i=Next[i])
  104. if(v[i]!=fa[u] && v[i]!=son[u])bfs(v[i]);
  105.  
  106. Add(u);
  107.  
  108. ans+=(ll)n*(n-)/-Sum-Sum2;
  109. }
  110. int main(){
  111. freopen("treecnt.in","r",stdin);
  112. freopen("treecnt.out","w",stdout);
  113. n=read();
  114. Q.clear();
  115. Q.insert();
  116. Q.insert(n+);
  117. Sum2=cal(n);
  118. rep(i,,n)Fa[i]=i,s[i]=,vis[i]=;
  119. rep(i,,n){
  120. int x=read(),y=read();
  121. add(x,y);
  122. add(y,x);
  123. }
  124. dfs1();
  125. dfs2();
  126. cout<<ans<<endl;
  127. return ;
  128. }

正解

18/9/21模拟赛-Updated的更多相关文章

  1. 【2018.10.18】noip模拟赛Day2 地球危机(2018年第九届蓝桥杯C/C++A组省赛 三体攻击)

    题目描述 三体人将对地球发起攻击.为了抵御攻击,地球人派出了 $A × B × C$ 艘战舰,在太 空中排成一个 $A$ 层 $B$ 行 $C$ 列的立方体.其中,第 $i$ 层第 $j$ 行第 $k ...

  2. 18.09.22模拟赛T2 历史

    网上基本上找不到这道题,何况LJJ还稍微改了一下...... 原题:传送门 题目描述 ljj 被S 国数不清的漂亮小姐姐所吸引,为了搞清楚为什么S 国有如此多的漂亮小姐姐,他决定研究S 国的历史. 根 ...

  3. 6.18 省选模拟赛 树 倍增 LCT

    LINK:树 考虑暴力 保存每个版本的父亲 然后暴力向上跳.得分20. 考虑离线 可以离线那么就可以先把树给搞出来 然后考虑求k级祖先 可以倍增求. 如何判断合法 其实要求路径上的边的时间戳<= ...

  4. 6.18 省选模拟赛 字符串 LCT SAM

    LINK:字符串 看起来很难做 考虑一种暴力 建立SAM后每次查询暴力扫儿子. 期望得分10分.实际得分10分. 另外一种发现每次扫儿子过于暴力 可以每次儿子向上做贡献 每次都暴力向上跳. 期望得分1 ...

  5. 4.18 省选模拟赛 无聊的计算器 CRT EXBSGS EXLucas

    算是一道很毒瘤的题目 考试的时候码+调了3h才搞定. op==1 显然是快速幂. op==2 有些点可以使用BSGS 不过后面的点是EXBSGS. 这个以前学过了 考试的时候还是懵逼.(当时还是看着花 ...

  6. [10.18模拟赛] 序列 (DP)

    [10.18模拟赛] 序列 题目描述 山山有一个整数序列s1,s2,-,sn,其中1≤si≤k. 求出有多少个准确移除m个元素后不同的序列.答案模(1e9+7) 输入 输入包括几个测试用例,并且由文件 ...

  7. [GRYZ]寒假模拟赛

    写在前面 这是首次广饶一中的OIERS自编自导,自出自做(zuo)的模拟赛. 鉴于水平气压比较低,机(wei)智(suo)的WMY/XYD/HYXZC就上网FQ下海找了不少水(fei)题,经过他们优( ...

  8. CH Round #48 - Streaming #3 (NOIP模拟赛Day1)

    A.数三角形 题目:http://www.contesthunter.org/contest/CH%20Round%20%2348%20-%20Streaming%20%233%20(NOIP模拟赛D ...

  9. 7.29NOIP模拟赛

    7.29NOIP模拟赛 T1 YSG (1s,64MB,ysg.in,ysg.out) 描述 ysg,yxy,azw 三人正在刷题. 他们每做一题的时间都是一个有理数. 如果在某一时刻,三人同时做完一 ...

随机推荐

  1. POJ2104 K-th Number(线段树,二分,vector)

    题意 不带修改区间第k小.(n<=100000) 题解 建立线段数和vector数组(vector为当前区间排列之后的序列)(归并) 然后对于每一个询问二分答案. 问题就转化为区间有多少数小于等 ...

  2. JDBC连接SQL Server遇到的问题

    需要使用到微软的JDBC sql server的驱动类,去官网下载jar包 使用的URL模式:"jdbc:sqlserver:地址:端口//;databaseName=YourDatabas ...

  3. 紫书 例题 10-10 UVa 10491(概率计算)

    公式很好推,表示被高中生物遗传概率计算虐过的人 这个公式简直不需要动脑 #include<cstdio> using namespace std; int main() { double ...

  4. linux学习之多高并发服务器篇(一)

    高并发服务器 高并发服务器 并发服务器开发 1.多进程并发服务器 使用多进程并发服务器时要考虑以下几点: 父最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符) 系统内创建进程 ...

  5. 找出BST里面与Target最接近的n个数

    http://www.cnblogs.com/jcliBlogger/p/4771342.html 这里给了两种解法,一种是利用C++的priority_queue,然后逐个node输入. 另一种是先 ...

  6. TCP/IP具体解释--TCP的分段和IP的分片

    写在前面: 分组能够发生在运输层和网络层.运输层中的TCP会分段,网络层中的IP会分片.IP层的分片很多其它的是为运输层的UDP服务的,因为TCP自己会避免IP的分片,所以使用TCP传输在IP层都不会 ...

  7. HDU 4572 Bottles Arrangement

    具体的证明:点击打开链接 我的想法: 要想保证题目所说 构造最小行的和,仅仅能是这样的情况 .....      m-3  m-2  m-1  m    |   m  m-1  m-2  m-3   ...

  8. cookies,sessionStorage和localStorage的区别

    共同点:都是保存在浏览器端,且同源的.区别:cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递.而sessionStorage和localStora ...

  9. 如何使用通用pe工具箱破解开机密码

    下载最新版的通用pe工具箱将u盘制作成启动盘,接着重启连续按热键进入到bios系统下,设置u盘为第一启动,保存重启. 1.这时候会进入通用pe工具箱的选择界面,我们选择第八个“运行Windows登陆密 ...

  10. Android控件-TabHost(一)

    什么是TabHost? TabHost组件的主要功能是可以进行应用程序分类管理,例如:在用户使用windows操作系统的时候,经常见到如图所示的图形界面.     TabHost选项卡,说到这个组件, ...