18/9/21模拟赛-Updated
18/9/21模拟赛
期望得分:100;实际得分:0 qwq
拿到题目第一眼,我去,这不是洛谷原题(仓鼠找Sugar)吗
又多看了几眼,嗯,对,除了是有多组数据外,就是原题
然后码码码。。。。自以为写的很对 qwq
评测结束后。。。为什么我T1没有输出啊啊啊。。。
经某童鞋帮忙,发现
第一次被文件输入输出坑 qwqwq。。。
加上后就A了,白丢100 pts 蓝瘦
思路:树剖分别求LCA,然后判断LCA是否在另一条路径上
不要忘记清空数组!
- #include <algorithm>
- #include <cstring>
- #include <cstdio>
- using namespace std;
- const int M = ;
- int T, n, m, tot;
- int to[M << ], net[M << ], head[M];
- int deep[M], top[M], dad[M], size[M];
- void add(int u, int v) {
- to[++tot] = v; net[tot] = head[u]; head[u] = tot;
- to[++tot] = u; net[tot] = head[v]; head[v] = tot;
- }
- void dfs(int now) {
- size[now] = ;
- deep[now] = deep[dad[now]] + ;
- for (int i = head[now]; i; i = net[i])
- if (to[i] != dad[now]) {
- dad[to[i]] = now;
- dfs(to[i]);
- size[now] += size[to[i]];
- }
- }
- void dfsl(int now) {
- int t = ;
- if (!top[now]) top[now] = now;
- for (int i = head[now]; i; i = net[i])
- if (to[i] != dad[now] && size[to[i]] > size[t])
- t = to[i];
- if (t) {
- top[t] = top[now];
- dfsl(t);
- }
- for (int i = head[now]; i; i = net[i])
- if (to[i] != dad[now] && to[i] != t)
- dfsl(to[i]);
- }
- int lca(int x, int y) {
- while (top[x] != top[y]) {
- if (deep[top[x]] < deep[top[y]])
- swap(x, y);
- x = dad[top[x]];
- }
- return deep[x] > deep[y] ? y : x;
- }
- void clear() {
- tot = ;
- memset(to, , sizeof to);
- memset(net, , sizeof net);
- memset(dad, , sizeof dad);
- memset(top, , sizeof top);
- memset(head, , sizeof head);
- memset(deep, , sizeof deep);
- memset(size, , sizeof size);
- }
- int main() {
- freopen("railway.in","r",stdin);
- freopen("railway.out","w",stdout);
- scanf("%d", &T);
- for (int q = ; q <= T; ++q) {
- if (q != ) clear();
- scanf("%d%d", &n, &m);
- for (int i = ; i < n; ++i) {
- int u, v;
- scanf("%d%d", &u, &v);
- add(u, v);
- }
- dfs();
- dfsl();
- for (int i = ; i <= m; ++i) {
- int a, b, c, d;
- scanf("%d%d%d%d", &a, &b, &c, &d);
- int S = lca(a, b);
- int R = lca(c, d);
- if (S < R) {
- swap(S, R);
- swap(a, c);
- swap(b, d);
- }
- if (lca(S, c) == S || lca(S, d) == S) printf("YES\n");
- else printf("NO\n");
- }
- }
- fclose(stdin); fclose(stdout);
- return ;
- }
期望得分:100? 实际得分:20 (那80pts的都TLE了。。。)
思路:线段树维护区间的最大最小值,然后枚举每一个区间求解
事实证明,我真的不会算时间复杂度 qwq
- #include <algorithm>
- #include <cstring>
- #include <cstdio>
- #ifdef WIN32
- #define LL "%I64d\n"
- #else
- #define LL "%lld\n"
- #endif
- using namespace std;
- typedef long long Ll;
- const int M = ;
- int n, m;
- Ll ans;
- int ll[M << ], rr[M << ];
- int maxn[M << ], minn[M << ];
- void update(int now) {
- maxn[now] = max(maxn[now << ], maxn[now << | ]);
- minn[now] = min(minn[now << ], minn[now << | ]);
- }
- void build(int now, int l, int r) {
- ll[now] = l; rr[now] = r;
- if (l == r) {
- scanf("%d", &maxn[now]);
- minn[now] = maxn[now];
- return ;
- }
- int mid = (l + r) >> ;
- build(now << , l, mid);
- build(now << | , mid + , r);
- update(now);
- }
- int query(int now, int l, int r) {
- if (ll[now] == l && rr[now] == r)
- return maxn[now];
- int mid = (ll[now] + rr[now]) >> ;
- if (l <= mid && mid < r) return max(query(now << , l, mid), query(now << | , mid + , r));
- else if (r <= mid) return query(now << , l, r);
- else return query(now << | , l, r);
- }
- int found(int now, int l, int r) {
- if (ll[now] == l && rr[now] == r)
- return minn[now];
- int mid = (ll[now] + rr[now]) >> ;
- if (l <= mid && mid < r) return min(found(now << , l, mid), found(now << | , mid + , r));
- else if (r <= mid) return found(now << , l, r);
- else return found(now << | , l, r);
- }
- void clear() {
- ans = ;
- memset(ll, , sizeof ll);
- memset(rr, , sizeof rr);
- memset(maxn, , sizeof maxn);
- memset(minn, , sizeof minn);
- }
- int main() {
- freopen("count.in","r",stdin);
- freopen("count.out","w",stdout);
- scanf("%d", &m);
- for (int q = ; q <= m; ++q) {
- if (q != ) clear();
- scanf("%d", &n);
- build(, , n);
- for (int i = ; i <= n; ++i)
- for (int j = i + ; j <= n; ++j)
- ans += (query(, i, j) - found(, i, j));
- printf(LL, ans);
- }
- fclose(stdin); fclose(stdout);
- return ;
- }
考场20pts代码
正解:因为排列是随机的,所以从每个点向后可能的差值最多 2logn 个,所以答案最多只可能有nlogn 种,用单调队列找出来统计即可
- #include<iostream>
- #include<algorithm>
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #include<cstdlib>
- using namespace std;
- typedef long long ll;
- typedef long double ld;
- typedef pair<int,int> pr;
- const double pi=acos(-);
- #define rep(i,a,n) for(int i=a;i<=n;i++)
- #define per(i,n,a) for(int i=n;i>=a;i--)
- #define Rep(i,u) for(int i=head[u];i;i=Next[i])
- #define clr(a) memset(a,0,sizeof a)
- #define pb push_back
- #define mp make_pair
- #define putk() putchar(' ')
- ld eps=1e-;
- ll pp=;
- ll mo(ll a,ll pp){if(a>= && a<pp)return a;a%=pp;if(a<)a+=pp;return a;}
- 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;}
- ll gcd(ll a,ll b){return (!b)?a:gcd(b,a%b);}
- ll read(){
- ll ans=;
- char last=' ',ch=getchar();
- while(ch<'' || ch>'')last=ch,ch=getchar();
- while(ch>='' && ch<='')ans=ans*+ch-'',ch=getchar();
- if(last=='-')ans=-ans;
- return ans;
- }
- void put(ll a){
- if(a<)putchar('-'),a=-a;
- int top=,q[];
- while(a)q[++top]=a%,a/=;
- top=max(top,);
- while(top--)putchar(''+q[top+]);
- }
- //head
- #define N 210000
- int n,a[N],f1[N],f2[N],q[N];
- ll s[N];
- void solved(){
- n=read();
- rep(i,,n)a[i]=read();
- a[n+]=n+;
- q[]=n+;
- int t=;
- per(i,n,){
- while(t && a[q[t]]<=a[i])--t;
- f1[i]=q[t];
- q[++t]=i;
- }
- a[n+]=;
- q[]=n+;
- t=;
- per(i,n,){
- while(t && a[q[t]]>=a[i])--t;
- f2[i]=q[t];
- q[++t]=i;
- }
- rep(i,,n)s[i]=;
- rep(i,,n){
- int z1=i,z2=i;
- while(z1!=n+ && z2!=n+){
- if(f1[z1]<=f2[z2]){
- int tt=max(z1,z2),zz=a[z1]-a[z2];
- z1=f1[z1];
- s[zz]+=max(z1,z2)-tt;
- }
- else{
- int tt=max(z1,z2),zz=a[z1]-a[z2];
- z2=f2[z2];
- s[zz]+=max(z1,z2)-tt;
- }
- }
- }
- ll ans=;
- rep(i,,n-)
- ans+=s[i]*i;
- cout<<ans<<endl;
- }
- int main(){
- freopen("count.in","r",stdin);
- freopen("count.out","w",stdout);
- int T=read();
- while(T--){
- solved();
- }
- return ;
- }
正解
比题解更好的做法 ——By lgj
分别求所有区间的最大值和、最小值和
用单调栈维护,用sum记录已经求过的区间的最大值的和
求最小值时,可将所有的数转为负数,重新跑一遍即可
最后将两次求出的值相加即可
- #include<cstdio>
- #include<cstdlib>
- #include<algorithm>
- #include<iostream>
- #define LL long long
- using namespace std;
- const LL MAXN = 1e5 + ;
- inline LL read() {
- char c = getchar(); LL x = , f = ;
- while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
- while(c >= '' && c <= '') x = x * + c - '', c = getchar();
- return x * f;
- }
- LL T, N;
- LL a[MAXN], q[MAXN];
- LL solve() {
- LL h = , t = , ans = , sum = ;
- for(LL i = ; i <= N; i++) {
- while(h <= t && a[i] > a[q[t]]) sum -= a[q[t]] * (q[t] - q[t - ]), t--;
- q[++t] = i;
- ans += a[i] * (q[t] - q[t - ]) + sum;
- sum += a[i] * (q[t] - q[t - ]);
- }
- return ans;
- }
- int main() {
- freopen("count.in", "r", stdin);
- freopen("count.out", "w", stdout);
- T = read();
- while(T--) {
- N = read();
- for(LL i = ; i <= N; i++) a[i] = read();
- LL ans = solve();
- for(LL i = ; i <= N; i++) a[i] = -a[i];
- LL ans2 = solve();
- cout << ans + ans2 << endl;
- }
- return ;
- }
% lgj dalao
期望得分:0;实际得分:0
一开始以为样例错了,死活推不出来
前一个小时做了前两题,剩下的时间大部分就在推样例发呆中度过了
最后半小时才发现读错题 qwq
然而暴力也写不完了。。。
正解:对于每一条边统计有多少个区间跨过这条边即可
统计这一问题的对偶问题,有多少个区间没跨过会更方便
使用启发式合并+并查集统计子树内的,使用启发式合并+set 统计子树外的
- #include<iostream>
- #include<algorithm>
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #include<cstdlib>
- #include<set>
- #include<ctime>
- using namespace std;
- typedef long long ll;
- typedef long double ld;
- typedef pair<int,int> pr;
- const double pi=acos(-);
- #define rep(i,a,n) for(int i=a;i<=n;i++)
- #define per(i,n,a) for(int i=n;i>=a;i--)
- #define Rep(i,u) for(int i=head[u];i;i=Next[i])
- #define clr(a) memset(a,0,sizeof a)
- #define pb push_back
- #define mp make_pair
- ld eps=1e-;
- ll pp=;
- ll mo(ll a,ll pp){if(a>= && a<pp)return a;a%=pp;if(a<)a+=pp;return a;}
- 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;}
- ll read(){
- ll ans=;
- char last=' ',ch=getchar();
- while(ch<'' || ch>'')last=ch,ch=getchar();
- while(ch>='' && ch<='')ans=ans*+ch-'',ch=getchar();
- if(last=='-')ans=-ans;
- return ans;
- }
- //head
- #define N 110000
- int head[N],Next[N*],v[N*],num,fa[N],son[N],sum[N],n,s[N],Fa[N];
- ll ans=,Sum,Sum2;
- bool vis[N];
- set<int>Q;
- set<int>::iterator it,it1,it2;
- int find(int x){
- if(x==Fa[x])return x;
- return Fa[x]=find(Fa[x]);
- }
- void add(int x,int y){
- v[++num]=y;Next[num]=head[x];head[x]=num;
- }
- void dfs1(int u){
- sum[u]=;son[u]=;
- for(int i=head[u];i;i=Next[i])
- if(v[i]!=fa[u]){
- fa[v[i]]=u;
- dfs1(v[i]);
- sum[u]+=sum[v[i]];
- if(!son[u] || sum[v[i]]>sum[son[u]])son[u]=v[i];
- }
- }
- ll cal(ll n){
- return n*(n-)/;
- }
- void Add(int u){
- Q.insert(u);
- it=Q.find(u);
- it1=it2=it;
- it1--;it2++;
- Sum2-=cal((*it2)-(*it1)-);
- Sum2+=cal((*it)-(*it1)-)+cal((*it2)-(*it)-);
- vis[u]=;
- if(vis[u-]){
- int fx=find(u-),fy=find(u);
- Sum+=(ll)s[fx]*s[fy];
- Fa[fx]=fy;
- s[fy]+=s[fx];
- }
- if(vis[u+]){
- int fx=find(u+),fy=find(u);
- Sum+=(ll)s[fx]*s[fy];
- Fa[fx]=fy;
- s[fy]+=s[fx];
- }
- }
- void bfs(int u){
- Add(u);
- for(int i=head[u];i;i=Next[i])
- if(v[i]!=fa[u])bfs(v[i]);
- }
- void clear(int u){
- s[u]=;vis[u]=;Fa[u]=u;
- for(int i=head[u];i;i=Next[i])
- if(v[i]!=fa[u])clear(v[i]);
- }
- void dfs2(int u){
- for(int i=head[u];i;i=Next[i])
- if(v[i]!=fa[u] && v[i]!=son[u]){
- dfs2(v[i]);
- clear(v[i]);
- Sum=;
- Q.clear();
- Q.insert();
- Q.insert(n+);
- Sum2=(ll)(n-)*n/;
- }
- if(son[u])dfs2(son[u]);
- for(int i=head[u];i;i=Next[i])
- if(v[i]!=fa[u] && v[i]!=son[u])bfs(v[i]);
- Add(u);
- ans+=(ll)n*(n-)/-Sum-Sum2;
- }
- int main(){
- freopen("treecnt.in","r",stdin);
- freopen("treecnt.out","w",stdout);
- n=read();
- Q.clear();
- Q.insert();
- Q.insert(n+);
- Sum2=cal(n);
- rep(i,,n)Fa[i]=i,s[i]=,vis[i]=;
- rep(i,,n){
- int x=read(),y=read();
- add(x,y);
- add(y,x);
- }
- dfs1();
- dfs2();
- cout<<ans<<endl;
- return ;
- }
正解
18/9/21模拟赛-Updated的更多相关文章
- 【2018.10.18】noip模拟赛Day2 地球危机(2018年第九届蓝桥杯C/C++A组省赛 三体攻击)
题目描述 三体人将对地球发起攻击.为了抵御攻击,地球人派出了 $A × B × C$ 艘战舰,在太 空中排成一个 $A$ 层 $B$ 行 $C$ 列的立方体.其中,第 $i$ 层第 $j$ 行第 $k ...
- 18.09.22模拟赛T2 历史
网上基本上找不到这道题,何况LJJ还稍微改了一下...... 原题:传送门 题目描述 ljj 被S 国数不清的漂亮小姐姐所吸引,为了搞清楚为什么S 国有如此多的漂亮小姐姐,他决定研究S 国的历史. 根 ...
- 6.18 省选模拟赛 树 倍增 LCT
LINK:树 考虑暴力 保存每个版本的父亲 然后暴力向上跳.得分20. 考虑离线 可以离线那么就可以先把树给搞出来 然后考虑求k级祖先 可以倍增求. 如何判断合法 其实要求路径上的边的时间戳<= ...
- 6.18 省选模拟赛 字符串 LCT SAM
LINK:字符串 看起来很难做 考虑一种暴力 建立SAM后每次查询暴力扫儿子. 期望得分10分.实际得分10分. 另外一种发现每次扫儿子过于暴力 可以每次儿子向上做贡献 每次都暴力向上跳. 期望得分1 ...
- 4.18 省选模拟赛 无聊的计算器 CRT EXBSGS EXLucas
算是一道很毒瘤的题目 考试的时候码+调了3h才搞定. op==1 显然是快速幂. op==2 有些点可以使用BSGS 不过后面的点是EXBSGS. 这个以前学过了 考试的时候还是懵逼.(当时还是看着花 ...
- [10.18模拟赛] 序列 (DP)
[10.18模拟赛] 序列 题目描述 山山有一个整数序列s1,s2,-,sn,其中1≤si≤k. 求出有多少个准确移除m个元素后不同的序列.答案模(1e9+7) 输入 输入包括几个测试用例,并且由文件 ...
- [GRYZ]寒假模拟赛
写在前面 这是首次广饶一中的OIERS自编自导,自出自做(zuo)的模拟赛. 鉴于水平气压比较低,机(wei)智(suo)的WMY/XYD/HYXZC就上网FQ下海找了不少水(fei)题,经过他们优( ...
- CH Round #48 - Streaming #3 (NOIP模拟赛Day1)
A.数三角形 题目:http://www.contesthunter.org/contest/CH%20Round%20%2348%20-%20Streaming%20%233%20(NOIP模拟赛D ...
- 7.29NOIP模拟赛
7.29NOIP模拟赛 T1 YSG (1s,64MB,ysg.in,ysg.out) 描述 ysg,yxy,azw 三人正在刷题. 他们每做一题的时间都是一个有理数. 如果在某一时刻,三人同时做完一 ...
随机推荐
- POJ2104 K-th Number(线段树,二分,vector)
题意 不带修改区间第k小.(n<=100000) 题解 建立线段数和vector数组(vector为当前区间排列之后的序列)(归并) 然后对于每一个询问二分答案. 问题就转化为区间有多少数小于等 ...
- JDBC连接SQL Server遇到的问题
需要使用到微软的JDBC sql server的驱动类,去官网下载jar包 使用的URL模式:"jdbc:sqlserver:地址:端口//;databaseName=YourDatabas ...
- 紫书 例题 10-10 UVa 10491(概率计算)
公式很好推,表示被高中生物遗传概率计算虐过的人 这个公式简直不需要动脑 #include<cstdio> using namespace std; int main() { double ...
- linux学习之多高并发服务器篇(一)
高并发服务器 高并发服务器 并发服务器开发 1.多进程并发服务器 使用多进程并发服务器时要考虑以下几点: 父最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符) 系统内创建进程 ...
- 找出BST里面与Target最接近的n个数
http://www.cnblogs.com/jcliBlogger/p/4771342.html 这里给了两种解法,一种是利用C++的priority_queue,然后逐个node输入. 另一种是先 ...
- TCP/IP具体解释--TCP的分段和IP的分片
写在前面: 分组能够发生在运输层和网络层.运输层中的TCP会分段,网络层中的IP会分片.IP层的分片很多其它的是为运输层的UDP服务的,因为TCP自己会避免IP的分片,所以使用TCP传输在IP层都不会 ...
- HDU 4572 Bottles Arrangement
具体的证明:点击打开链接 我的想法: 要想保证题目所说 构造最小行的和,仅仅能是这样的情况 ..... m-3 m-2 m-1 m | m m-1 m-2 m-3 ...
- cookies,sessionStorage和localStorage的区别
共同点:都是保存在浏览器端,且同源的.区别:cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递.而sessionStorage和localStora ...
- 如何使用通用pe工具箱破解开机密码
下载最新版的通用pe工具箱将u盘制作成启动盘,接着重启连续按热键进入到bios系统下,设置u盘为第一启动,保存重启. 1.这时候会进入通用pe工具箱的选择界面,我们选择第八个“运行Windows登陆密 ...
- Android控件-TabHost(一)
什么是TabHost? TabHost组件的主要功能是可以进行应用程序分类管理,例如:在用户使用windows操作系统的时候,经常见到如图所示的图形界面. TabHost选项卡,说到这个组件, ...