【牛客 - 370A】签到题(线段树扫描线 或 STLset)(求线段并)

题干:

链接:https://ac.nowcoder.com/acm/contest/370/A
来源:牛客网
 

恭喜你找到了本场比赛的签到题!
为了让大家都有抽奖的机会,只需要复制粘贴以下代码(并且稍微填下空)即可 AC:
(我超良心的)

#include <algorithm>#include <iostream>#include <cstring>#include <climits>#include <cstdio>#include <vector>#include <cstdlib>#include <ctime>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>#define fi first#define lc (x<<1)#define se second#define U unsigned#define rc (x<<1|1)#define Re register#define LL long long#define MP std::make_pair#define CLR(i,a) memset(i,a,sizeof(i))#define FOR(i,a,b) for(Re int i = a;i <= b;++i)#define ROF(i,a,b) for(Re int i = a;i >= b;--i)#define SFOR(i,a,b,c) for(Re int i = a;i <= b;i+=c)#define SROF(i,a,b,c) for(Re int i = a;i >= b;i-=c)#define DEBUG(x) std::cerr << #x << '=' << x << std::endlconst int MAXN = 1000000+5;int N,maxL;std::set<std::pair<int,int> > L;inline int calc(){// 返回 set 中所有线段的并长度。(每个 pair 表示一个线段[first,second]}int main(){scanf("%d%d",&N,&maxL);while(N--){int opt,x,y;scanf("%d%d%d",&opt,&x,&y);if(opt == 1){if(L.find(MP(x,y)) != L.end()) continue;L.insert(MP(x,y));}if(opt == 2){if(L.find(MP(x,y)) == L.end()) continue;L.erase(MP(x,y));}if(opt == 3){printf("%d\n",calc());}}return 0;}

输入描述:

第一行两个整数 N,L,意义如代码所述。接下来 N 行,每行三个整数 opt,l,r,意义如代码所述。

输出描述:

对于每一组 opt=3 的询问输出一个答案。

示例1

输入

复制

6 13
1 1 2
1 4 5
1 4 7
1 6 9
1 12 13
3 3 3

输出

复制

10

说明

我们依次加入线段[1,2],[4,5],[4,7],[6,9],[12,13], 它们的并集长度为 10.

备注:

N≤105,L≤105,0≤l≤r≤LN≤105,L≤105,0≤l≤r≤L,保证数据随机生成。

解题报告:

题目需要你维护一个线段集合,支持插入线段,删除线段和求线段并长度。

我们可以用简化版的扫描线来实现,当然因为数据随机,暴力也可以过。。。。

AC代码1:(直接暴力)(400ms-800ms)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 1e5 + 5;
set<int> ss[MAX];
int vis[MAX];
int main()
{int n,maxl,ans=0;scanf("%d%d", &n, &maxl);for(int i = 1; i<=n; i++) {int op,l,r;scanf("%d%d%d",&op,&l,&r);if(l > r) swap(l,r);if(op == 1) {if(ss[l].find(r)!=ss[l].end()) continue;ss[l].insert(r);for(int j = l; j<=r; j++) {if(vis[j] == 0) ans++;vis[j]++;}}if(op == 2) {if (ss[l].find(r)==ss[l].end()) continue;ss[l].erase(r);for(int j = l; j<=r; j++) {if(vis[j] == 1) ans--;vis[j]--;}}if(op == 3) printf("%d\n",ans);}return 0 ;}

AC代码2:(扫描线)(100ms)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
set<int> s[100005];
struct Tree {int l,r;int val;int laz; 
} tree[100005 * 4];
inline int len(int cur) {return tree[cur].r - tree[cur].l + 1;
}
void pushup(int cur) {if(tree[cur].laz > 0) tree[cur].val = len(cur);else if (tree[cur].l == tree[cur].r) tree[cur].val = 0;else tree[cur].val = tree[cur*2].val + tree[cur*2+1].val;
}
void pushdown(int cur) {if(tree[cur].laz == 0) return ;tree[cur*2].laz += tree[cur].laz;tree[cur*2+1].laz += tree[cur].laz;tree[cur*2].val += tree[cur].laz;tree[cur*2+1].val += tree[cur].laz;tree[cur].laz = 0;
} 
void build(int l,int r,int cur) {tree[cur].val=0;tree[cur].l = l;tree[cur].r = r;if(l == r) return ;int m = (l+r)>>1;build(l,m,cur*2);build(m+1,r,cur*2+1);
}
void update(int pl,int pr,int val,int cur) {if(pl <= tree[cur].l && pr >= tree[cur].r) {tree[cur].laz += val;pushup(cur);return ;}//pushdown(cur);if(tree[cur*2].r >= pl) update(pl,pr,val,cur*2);if(tree[cur*2+1].l <= pr) update(pl,pr,val,cur*2+1);pushup(cur);
}
int main() {int ans=0,N,maxL;scanf("%d%d", &N, &maxL);build(1,maxL,1);while (N--) {int opt, x, y;scanf("%d%d%d", &opt, &x, &y);if (x>y) swap(x,y);if (opt == 1) {if (s[x].find(y)!=s[x].end()) continue;s[x].insert(y);update(x,y,1,1);}if (opt == 2) {if (s[x].find(y)==s[x].end()) continue;s[x].erase(y);	update(x,y,-1,1);}if (opt == 3) {printf("%d\n", tree[1].val);}}return 0;
}

AC代码3:(扫描线+pushdown版本)(应该是可以支持区间覆盖情况查询的)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
set<int> s[100005];
struct Tree {int l,r;int val;int laz; 
} tree[100005 * 4];
inline int len(int cur) {return tree[cur].r - tree[cur].l + 1;
}
void pushup(int cur) {if(tree[cur].laz > 0) tree[cur].val = len(cur);else if (tree[cur].l == tree[cur].r) tree[cur].val = 0;else tree[cur].val = tree[cur*2].val + tree[cur*2+1].val;
}
void pushdown(int cur) {if(tree[cur].laz == 0) return ;tree[cur*2].laz += tree[cur].laz;tree[cur*2+1].laz += tree[cur].laz;
//	tree[cur*2].val += tree[cur].laz;
//	tree[cur*2+1].val += tree[cur].laz;
//	tree[cur].laz = 0;
} 
void build(int l,int r,int cur) {tree[cur].val=0;tree[cur].l = l;tree[cur].r = r;if(l == r) return ;int m = (l+r)>>1;build(l,m,cur*2);build(m+1,r,cur*2+1);
}
void update(int pl,int pr,int val,int cur) {if(pl <= tree[cur].l && pr >= tree[cur].r) {tree[cur].laz += val;pushup(cur);return ;}pushdown(cur);if(tree[cur*2].r >= pl) update(pl,pr,val,cur*2);if(tree[cur*2+1].l <= pr) update(pl,pr,val,cur*2+1);pushup(cur);
}
int main() {int ans=0,N,maxL;scanf("%d%d", &N, &maxL);build(1,maxL,1);while (N--) {int opt, x, y;scanf("%d%d%d", &opt, &x, &y);if (x>y) swap(x,y);if (opt == 1) {if (s[x].find(y)!=s[x].end()) continue;s[x].insert(y);update(x,y,1,1);}if (opt == 2) {if (s[x].find(y)==s[x].end()) continue;s[x].erase(y);	update(x,y,-1,1);}if (opt == 3) {printf("%d\n", tree[1].val);}}return 0;
}

标程:

我们考虑一种非常暴力的做法:对于这个数轴建出线段树,然后插入删除对应了区间加值操作。
我们来考虑一下询问操作:最朴素的方法是查询每个点是否有值然后统计答案。我们可以考虑对每一个线段树上的节点维护一个 min 值,这样遍历到一个节点的时候如果当前节点的 min > 0 那么说明这个线段树节点对应的区间是所有线段并的一部分。
当然这样的话还是不一定能过的,但是注意到数据随机生成,所以查询操作仅为总操作的1313 ,且删除操作大概率不会触发。

const int MAXN = 100000+5;
#define lc (x<<1)
#define rc (x<<1|1)
int min[MAXN<<2],tag[MAXN<<2];inline void pushup(int x){min[x] = std::min(min[lc],min[rc]);
}inline void cover(int x,int l,int r,int delta){min[x] += delta;tag[x] += delta;
}inline void pushdown(int x,int l,int r){if(tag[x]){int mid = (l + r) >> 1;cover(lc,l,mid,tag[x]);cover(rc,mid+1,r,tag[x]);tag[x] = 0;}
}inline void modify(int x,int l,int r,int L,int R,int delta){if(l == L && R == r){cover(x,l,r,delta);return;}pushdown(x,l,r);int mid = (l + r) >> 1;if(R <= mid) modify(lc,l,mid,L,R,delta);else if(L > mid) modify(rc,mid+1,r,L,R,delta);else modify(lc,l,mid,L,mid,delta),modify(rc,mid+1,r,mid+1,R,delta);pushup(x);
}inline int query(int x,int l,int r){if(min[x] != 0) return r-l+1;if(l == r) return min[x] != 0;int mid = (l + r) >> 1;pushdown(x,l,r);return query(lc,l,mid)+query(rc,mid+1,r);
}std::map<P,bool> S;
int L = 0;
int main(){int N;scanf("%d%d",&N,&L);while(N--){int opt,x,y;scanf("%d%d%d",&opt,&x,&y);if(opt == 1){if(S[MP(x,y)]) continue;S[MP(x,y)] = true;// L = std::max(L,y);modify(1,1,L,x,y,1);}if(opt == 2){if(!S[MP(x,y)]) continue;S[MP(x,y)] = false;modify(1,1,L,x,y,-1);}if(opt == 3){printf("%d\n",query(1,1,L));}}return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440793.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java sqlserver分页查询_SQLServer之常用的分页查询语句介绍

在SqlServer中&#xff0c;分页查询是经常用到的查询语句&#xff0c;一个好的分页查询语句&#xff0c;不能能将代码省略&#xff0c;还能提高运行效率&#xff0c;下面我们来探讨一下SQLServer中的分页查询语句。具体的业务逻辑是这样的&#xff0c;我数据库中有100条数据&am…

【牛客 - 370H】Rinne Loves Dynamic Graph(分层图最短路)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/370/H 来源&#xff1a;牛客网 Rinne 学到了一个新的奇妙的东西叫做动态图&#xff0c;这里的动态图的定义是边权可以随着操作而变动的图。 当我们在这个图上经过一条边的时候&#xff0c;这个图上所…

中位数及带权中位数问题(转)

先从一到简单的题看起&#xff1a; 士兵站队问题 在一个划分成网格的操场上&#xff0c;n个士兵散乱地站在网格点上。网格点由整数坐标(x,y)表示。士兵们可以沿网格边上、下、左、右移动一步&#xff0c;但在同一时刻任一网格点上只能有一名士兵。按照军官的命令&#xff0c;…

java编写学籍管理系统_java学籍管理系统源代码.doc

java学籍管理系统源代码package zuoye;//主类import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.io.*;import java.util.Hashtable;public class ManagerWindow extends JFrame implements ActionListener{InputStudent 基本信息录入null;ModifySit…

*【SGU - 114】Telecasting station (带权中位数 或 三分)

题干&#xff1a; Every city in Berland is situated on Ox axis. The government of the country decided to build new telecasting station. After many experiments Berland scientists came to a conclusion that in any city citizens displeasure is equal to product…

java的et5_Javascript与java相同的3des加密(使用etdesede/CBC/PKCS5Padding )

在某个项目中&#xff0c;需要开发一个与native相对应的web前端app&#xff0c;后台用的是java restful接口&#xff0c;请求数据时需要用的3des加密。如果想要请求接口&#xff0c;则需要javascript的加密与java相同&#xff0c;于是在baidu与google进行了大量搜索&#xff0c…

*【HDU - 4272 】LianLianKan (dfs 或 状压dp,贪心不行)

题干&#xff1a; I like playing game with my friend, although sometimes looks pretty naive. Today I invent a new game called LianLianKan. The game is about playing on a number stack. Now we have a number stack, and we should link and pop the same element…

java中的values函数_巧用valueat函数(快逸免费版)

在制作报表时&#xff0c;经常会遇到将数据库里一列数据按照条件取值后&#xff0c;分为多列显示的需求&#xff0c;例如&#xff1a;数据库中有一列名为type的数据&#xff0c;在报表中&#xff0c;第一列选择type为1的数据&#xff0c;第二列选择type为2的数据。由于受到扩展…

Java设计流程执行器_Java进阶面试精选系列:SpringMVC+SpringBoot+Hibernate+Mybatis+设计模式...

小编精心收集&#xff1a;为金三银四准备&#xff0c;以下面试题先过一遍&#xff0c;为即将到了的面试做好准备&#xff0c;也过一遍基础知识点。一、Spring/Spring MVC1.为什么要使用 spring&#xff1f;2.解释一下什么是 aop&#xff1f;3.解释一下什么是 ioc&#xff1f;3.…

【CCFCSP - 201403-4】无线网络(分层图最短路)

题干&#xff1a; 试题编号&#xff1a;201403-4试题名称&#xff1a;无线网络时间限制&#xff1a;1.0s内存限制&#xff1a;256.0MB问题描述&#xff1a; 问题描述   目前在一个很大的平面房间里有 n 个无线路由器,每个无线路由器都固定在某个点上。任何两个无线路由器只要…

【牛客 - 370E】Rinne Loves Gift(Bellman_Ford判负环,二分,分数规划)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/370/E 来源&#xff1a;牛客网 Rinne 喜欢礼物&#xff0c;也喜欢送礼物 圣诞节快到了&#xff0c;Rinne 要去给给住在城市里的人送礼物 城市的交通可以抽象成一个 n 个点 m 条边的有向图 每条边上有…

【POJ - 2976】【ZOJ - 3068】【SCU - 2992】Dropping tests (01分数规划)

题干&#xff1a; In a certain course, you take n tests. If you get ai out of bi questions correct on test i, your cumulative average is defined to be . Given your test scores and a positive integer k, determine how high you can make your cumulative aver…

重写过的url 怎么获取当前页面url java_网站URL重写(Java UrlRewrite 的使用)

现在大部分的网站和商城都会使用到URL重写&#xff0c;接触到这个&#xff0c;也是因为正在做的电子商务商城。URL重写&#xff0c;是将原有的URL采用另一种规则来显示&#xff0c;使得用户方便访问同时也屏蔽一些信息。在此说下它的好处&#xff0c;在开发过程中&#xff0c;经…

【51nod - 1050】循环数组最大子段和(dp)

题干&#xff1a; N个整数组成的循环序列a[1],a[2],a[3],…,a[n]&#xff0c;求该序列如a[i]a[i1]…a[j]的连续的子段和的最大值&#xff08;循环序列是指n个数围成一个圈&#xff0c;因此需要考虑a[n-1],a[n],a[1],a[2]这样的序列&#xff09;。当所给的整数均为负数时和为0。…

Java行业情景分析_Java 设计模式情景分析——单例模式

单例模式可以说是应用最广的模式之一&#xff0c;在应用单例模式时&#xff0c;单例对象的类必须保证只有一个实例存在&#xff0c;而且可以自行实例化并向整个系统提供这个实例。一般在不能自由构造对象的情况下&#xff0c;就会使用单例设计模式&#xff0c;例如创建一个对象…

笔试题 - 汽车加油问题

题干&#xff1a; 第一行输入n&#xff0c;k&#xff0c;代表共有k个加油站&#xff0c;加满油后可以跑n公里。 第二行k1个数&#xff0c;其中前k个数代表加油站的位置&#xff0c;第k1个数代表终点的位置。 一辆车从坐标零点加满油后出发&#xff0c;问最少加几次油&#xff0…

php实现播放直播_PHP直播技术分享(一:实现直播)

推流服务器采用的是自搭的推流服务器 , 自己玩玩 做外包项目还是去搞七牛云/阿里这样的服务器吧,开始bb-----1:技术栈image.jpeg2:开发中业务(1)主播申请时创建个秘钥 , 这个秘钥随时字符串即可到时候根据字符串找到拉流的直播位置存数据库包括推流地址image.png3:配置nginx-rt…

笔试题 - 阶乘问题

题干&#xff1a; 【题意】 给你一个数组n&#xff08;1<n<1e5&#xff09; 让你输出有多少数的阶乘后恰好有n个0&#xff0c;并依次输出。 【类型】 二分or暴力 【分析】 肯定满足&#xff0c;数字越大&#xff0c;其后的0的个数也就越多。 于是我们可以二分出最小的l&…

php获取location,php获取header[‘location’]信息常见问题

15/01/31本文关键字: 302, header, location//初始化url信息$host “#8221;;$url$host.”l/rzTf7ap2viw/&iid222004556&resourceId0_04_05_99/v.swf”;//按照字段获取header响应信息$headers get_headers($url, TRUE);//获取这个土豆的302跳转地址$u302 $headers[“Lo…

【计蒜客 - 蓝桥训练】蒜厂年会(单调队列优化dp,循环数列的最大子段和)

题干&#xff1a; 在蒜厂年会上有一个抽奖&#xff0c;在一个环形的桌子上&#xff0c;有 nn 个纸团&#xff0c;每个纸团上写一个数字&#xff0c;表示你可以获得多少蒜币。但是这个游戏比较坑&#xff0c;里面竟然有负数&#xff0c;表示你要支付多少蒜币。因为这些数字都是…