Codeforces Round #395 (Div. 1)
比赛链接:http://codeforces.com/contest/763
A题:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=;
int n,tot,now[N],prep[N<<],son[N<<],c[N],a[N];
void read(int &x){
x=; int f=; char ch;
for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') f=-;
for (;isdigit(ch);ch=getchar()) x=x*+ch-''; x*=f;
}
void add(int u,int v){tot++,prep[tot]=now[u],now[u]=tot,son[tot]=v;}
int main(){
read(n);
for (int u,v,i=;i<n;i++){
read(u),read(v);
add(u,v),add(v,u);
}
for (int i=;i<=n;i++) read(c[i]);
for (int i=;i<=n;i++)
for (int j=now[i],k=son[j];j;j=prep[j],k=son[j]){
if (i<k&&c[i]!=c[k]) a[i]++,a[k]++;
}
int cnt=,id;
for (int i=;i<=n;i++) if (a[i]>=) cnt++,id=i;
if (cnt>) puts("NO");
else if (cnt==){
for (int i=now[id],j=son[i];i;i=prep[i],j=son[i]) if (c[id]!=c[j]) a[j]--;
for (int i=;i<=n;i++) if (i!=id&&a[i]){puts("NO");return ;}
puts("YES"); printf("%d\n",id);
}else{
cnt=;
for (int i=;i<=n;i++) if (a[i]) cnt++,id=i;
if (cnt>) puts("NO");
else if (cnt==) printf("YES\n%d\n",id);
else printf("YES\n%d\n",);
}
return ;
}
题目大意:给定一棵n个节点的树,每个点有个颜色,询问是否能以某个点为树根时,所有节点(树根除外)的子树中的颜色一致,有则输出YES,且输出树根的编号,否则输出NO; n,color[i]<=10^5;
做法:很容易yy出一种做法,就是记录每个点周围与它颜色不一致的节点个数,显然我们把这个值最大的那个点作为树根时最有可能合法嘛,那么找出树根,大力check一下即可。
B题:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int main(){
int n,x1,y1,x2,y2;
cin>>n; puts("YES");
while (n--){
cin>>x1>>y1>>x2>>y2;
cout<<(x1&)*+(y1&)+<<endl;
}
return ;
}
题目大意:给你n(n<=500000)个矩形,边长为奇数,矩阵不能相交,但是能相邻(也就是边有交集,且len>0),我们要用4种颜色去给矩形染色,要求相邻的矩形颜色不同,存在方案,则输出YES,并且要输出每个矩形的颜色,1<=color<=4,否则输出NO;
做法:根据数学中的四色定理可知,一定存在某种方案,那么,我们该怎么构造一种方案,这题有个重要的性质,边长为奇数,奇数有什么性质?奇数+奇数=偶数,偶数+奇数=奇数,也就是说一个数加上一个奇数,那么这个数的奇偶性就会发生改变,一种神奇的思路:取矩形的左上端点(x,y)来分类,
1.x为奇数,y为偶数,染为颜色1;
2.x为奇数,y为奇数,染为颜色2;
3.x为偶数,y为偶数,染为颜色3;
4.x为偶数,y为奇数,染为颜色4;
证明:如果两个矩形相邻,设这2个矩形的左上端点为(x1,y1),(x2,y2),由于矩形的边长为奇数,(x1,x2奇偶性不同),(y1,y2奇偶性不同)这两个条件至少成立一个,此时他们一定具有不同的颜色,得证。
E题:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#define PI pair<int,int>
#define mp(a,b) make_pair(a,b)
using namespace std;
const int N=,M=N*,K=N*;
int n,k,m,q,wi[K][],fa[M],ans[N],son[M][],smax[M],val[M],smax_id[M],tree[N];
vector <PI> vec[N],a[N];
void read(int &x){
x=; int f=; char ch;
for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') f=-;
for (;isdigit(ch);ch=getchar()) x=x*+ch-''; x*=f;
}
struct T{
int lowbit(int x){return x&(-x);}
void insert(int x,int y){for (int i=x;i<=n;i+=lowbit(i)) tree[i]+=y;}
int query(int x){
int sum=;
for (int i=x;i;i-=lowbit(i)) sum+=tree[i];
return sum;
}
}t;
struct link_cut_tree{
bool rev[M];
int which(int x){return son[fa[x]][]==x;}
bool isroot(int x){return son[fa[x]][]!=x&&son[fa[x]][]!=x;}
void update(int x){
smax[x]=val[x],smax_id[x]=x;
if (son[x][]&&smax[son[x][]]>smax[x]) smax[x]=smax[son[x][]],smax_id[x]=smax_id[son[x][]];
if (son[x][]&&smax[son[x][]]>smax[x]) smax[x]=smax[son[x][]],smax_id[x]=smax_id[son[x][]];
}
void pushdown(int x){
if (!rev[x]) return;
rev[x]^=,swap(son[x][],son[x][]);
if (son[x][]) rev[son[x][]]^=;
if (son[x][]) rev[son[x][]]^=;
}
void relax(int x){
if (!isroot(x)) relax(fa[x]);
pushdown(x);
}
void rotate(int x){
int y=fa[x],d=which(x),dd=which(y);
if (!isroot(y)) son[fa[y]][dd]=x; fa[x]=fa[y];
fa[son[x][d^]]=y,son[y][d]=son[x][d^];
fa[y]=x,son[x][d^]=y,update(y);
}
void splay(int x){
relax(x);
while (!isroot(x)){
if (isroot(fa[x])) rotate(x);
else if (which(x)==which(fa[x])) rotate(fa[x]),rotate(x);
else rotate(x),rotate(x);
}
update(x);
}
void access(int x){for (int p=;x;x=fa[x]) splay(x),son[x][]=p,p=x,update(x);}
void make_root(int x){access(x),splay(x),rev[x]^=;}
void link(int u,int v){make_root(u),fa[u]=v;}
void cut(int u,int v){make_root(u),access(v),splay(v),son[v][]=fa[u]=,update(v);}
int find_root(int x){
access(x),splay(x);
while (){
pushdown(x);
if (son[x][]) x=son[x][];
else return x;
}
}
void split(int u,int v){make_root(u),access(v),splay(v);}
int query(int u,int v){split(u,v);return smax_id[v];}
}lct;
int main(){
read(n),read(k),read(m);
for (int u,v,i=;i<=m;i++){
read(u),read(v); if (u>v) swap(u,v);
vec[u].push_back(mp(v,i)),wi[i][]=u,wi[i][]=v;
}
for (int i=;i<=n;i++) val[i]=,lct.update(i);
for (int i=;i<=m;i++) val[n+i]=wi[i][],lct.update(n+i);
read(q);
for (int l,r,i=;i<=q;i++){
read(l),read(r);
a[l].push_back(mp(r,i));
}
for (int i=n;i>=;i--){
for (int u,v,j=;j<vec[i].size();j++){
int x=vec[i][j].second;
u=wi[x][],v=wi[x][];
if (lct.find_root(u)!=lct.find_root(v)) lct.link(u,x+n),lct.link(v,x+n),t.insert(v,);
else{
int y=lct.query(u,v)-n;
if (wi[y][]>wi[x][]){
t.insert(wi[y][],-);
t.insert(wi[x][],);
lct.cut(y+n,wi[y][]),lct.cut(y+n,wi[y][]);
lct.link(x+n,u),lct.link(x+n,v);
}
}
}
for (int j=;j<(int)a[i].size();j++){
int x=a[i][j].first;
ans[a[i][j].second]=x-i+-t.query(x);
}
}
for (int i=;i<=q;i++) printf("%d\n",ans[i]);
return ;
}
题目大意:给n个点,m条边,然后q个询问,每次询问[l,r]区间中所有点带上其两两点之间的边组成的图的连通分量个数,n,q<=10^5,m<=500000;
做法:
做法1:分治+可持久化并查集,复杂度nlogn^3,这题过不了。
做法2:离线处理+lct维护mst,这种做法很神奇,是我看题解的时候学到的,大致做法如下:将所有询问按照左端点排序,然后按左端点从大到小考虑,做到所有左端点为l的询问时,我们将所有边(u,v),满足u>=l,u<v的边,令其权值为v,即可参与mst的构建,这个过程去lct维护,对于一个询问l,r,答案就是r-l+1-此时mst中权值<=r的边的条数,这个用树状数组维护即可,总复杂度nlogn,十分优秀的做法。
Codeforces Round #395 (Div. 1)的更多相关文章
- Codeforces Round #395 (Div. 2)(A.思维,B,水)
A. Taymyr is calling you time limit per test:1 second memory limit per test:256 megabytes input:stan ...
- Codeforces Round #395 (Div. 2) D. Timofey and rectangles
地址:http://codeforces.com/contest/764/problem/D 题目: D. Timofey and rectangles time limit per test 2 s ...
- Codeforces Round #395 (Div. 2) C. Timofey and a tree
地址:http://codeforces.com/contest/764/problem/C 题目: C. Timofey and a tree time limit per test 2 secon ...
- Codeforces Round #395 (Div. 2)B. Timofey and cubes
地址:http://codeforces.com/contest/764/problem/B 题目: B. Timofey and cubes time limit per test 1 second ...
- Codeforces Round #395 (Div. 2)(未完)
2.2.2017 9:35~11:35 A - Taymyr is calling you 直接模拟 #include <iostream> #include <cstdio> ...
- Codeforces Round #395 (Div. 2)
今天自己模拟了一套题,只写出两道来,第三道时间到了过了几分钟才写出来,啊,太菜了. A. Taymyr is calling you 水题,问你在z范围内 两个序列 n,2*n,3*n...... ...
- 【分类讨论】Codeforces Round #395 (Div. 2) D. Timofey and rectangles
D题: 题目思路:给你n个不想交的矩形并别边长为奇数(很有用)问你可以可以只用四种颜色给n个矩形染色使得相接触的 矩形的颜色不相同,我们首先考虑可不可能,我们分析下最多有几个矩形互相接触,两个时可以都 ...
- 【树形DP】Codeforces Round #395 (Div. 2) C. Timofey and a tree
标题写的树形DP是瞎扯的. 先把1看作根. 预处理出f[i]表示以i为根的子树是什么颜色,如果是杂色的话,就是0. 然后从根节点开始转移,转移到某个子节点时,如果其子节点都是纯色,并且它上面的那一坨结 ...
- Codeforces Round #395 (Div. 2) C
题意 : 给出一颗树 每个点都有一个颜色 选一个点作为根节点 使它的子树各自纯色 我想到了缩点后check直径 当<=3的时候可能有解 12必定有解 3的时候需要check直径中点的组成点里是否 ...
随机推荐
- ubuntu 16.04 数据库mysql安装与管理
1.安装mysql的客户端与服务器端 $>sudo apt-get install mysql-server mysql-client 2.管理服务 1.启动 $>sudo service ...
- 在rubymine中集成heroku插件
先安装heroku,参见http://www.cnblogs.com/jecyhw/p/4906990.html Heroku安装之后,就自动安装上git,目录为C:\Program Files (x ...
- Python面向对象之多态
多态 面向对象三大特性 封装 根据职责将属性和方法封装到一个抽象的类中:--定义类的准则 继承 实现代码的重用,相同的代码不需要重复的编写:--设计类的技巧:子类针对自己的需求,编写特定的代码: 多态 ...
- HUAS Summer Contest#4 D题 DP
Description Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了.要申请国外的任何大学,你都要交纳一定的申请费用,这可是很惊人的 ...
- java项目连接access数据库
1.导入Access_JDBC30.jar到项目中 jar包百度云链接:https://pan.baidu.com/s/10HFM3HomMArvfHjklA_1MA 密码:0qxp 项目名称-> ...
- xcap发包工具的简单使用3(报文描述)
之前详细介绍了如何构造以及发送报文,现在简单对报文描述一下 1.Ethernet MAC:填写报文目的mac和源mac地址 Vlan:支持单vlan,QinQ,如果有更多的vlan,请填写在“More ...
- HDU 2442
状态压缩DP , 和HDU2280极其相似 #include <cstdio> #include <cstring> #include <iostream> usi ...
- 【ZZ】神与学霸的区别
神与学霸的共同点是积点都令人发指得高,这也是他们的主要特征,或者说是基本特征.但是他们的区别也是很大的. 平时打电话给普通人:喂在干嘛? 玩 玩什么? 逛街/唱k/打游戏/看电影/睡觉/... 打电话 ...
- Jquery EasyUI动态生成Tab
function addTab(title, url) { if ($('#tt').tabs('exists', title)) { $('#tt').tabs('select', title); ...
- 洛谷——P1164 小A点菜
P1164 小A点菜 题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:“随便点”. 题目描述 不过u ...