发现这跟\(Gold\)难度简直天差地别啊。。

\(T1\)

传送门

解题思路

  这道题还是很可做的,发现题意可以传化成一棵树每次从叶子节点删边,然后有\(m\)条限制,形如\(a\)在\(b\)前面删去。发现\(a\)在\(b\)前面删去其实就是\(ban\)掉一棵树上一段或两段连续的\(dfs\)序,这个讨论一下关系即可。这样就可以树剖+线段树维护,但是直接做只有\(88\)分,因为没有考虑不合法的情况,判不合法的情况可以根据删除关系建一张有向图,然后最后判断有无环即可。

代码

#include<bits/stdc++.h>

using namespace std;
const int N=100005; inline int rd(){
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return f?x:-x;
} int n,m,num,siz[N],top[N],son[N],id[N],fa[N],dep[N],f[N][20];
int vis[N],tot;
bool use[N],tt[N];
vector<int> v[N],G[N]; struct Segment_Tree{
#define mid ((l+r)>>1)
int sum[N<<2],tag[N<<2];
void pushdown(int x){
sum[x<<1]|=tag[x];
sum[x<<1|1]|=tag[x];
tag[x<<1]|=tag[x];
tag[x<<1|1]|=tag[x];
tag[x]=0;
}
void update(int x,int l,int r,int L,int R){
if(L>R) return ;
if(L<=l && r<=R) {sum[x]=tag[x]=1; return;}
if(tag[x]) pushdown(x);
if(L<=mid) update(x<<1,l,mid,L,R);
if(mid<R) update(x<<1|1,mid+1,r,L,R);
sum[x]=(sum[x<<1]|sum[x<<1|1]);
}
int query(int x,int l,int r,int pos){
if(l==r) return sum[x];
if(tag[x]) pushdown(x);
if(pos<=mid) return query(x<<1,l,mid,pos);
return query(x<<1|1,mid+1,r,pos);
}
#undef mid
}tree; void dfs1(int x,int F){
siz[x]=1; fa[x]=F; int maxson=-1;
f[x][0]=F;
for(int i=1;i<=17;i++)
f[x][i]=f[f[x][i-1]][i-1];
for(int i=0;i<v[x].size();i++){
int u=v[x][i]; if(u==F) continue;
dep[u]=dep[x]+1; dfs1(u,x); siz[x]+=siz[u];
if(siz[u]>maxson) maxson=siz[u],son[x]=u;
}
} void dfs2(int x,int topf){
top[x]=topf; id[x]=++num;
if(!son[x]) return;
dfs2(son[x],topf); int u;
for(int i=0;i<v[x].size();i++){
u=v[x][i]; if(u==fa[x] || u==son[x]) continue;
dfs2(u,u);
}
} int jump(int x,int D){
for(int i=17;~i;i--)
if(dep[f[x][i]]>=D) x=f[x][i];
return x;
} void dfs(int x,int F){
use[x]=1;
for(int i=0;i<v[x].size();i++){
int u=v[x][i]; if(u==F || use[u]) continue;
// cout<<u<<" "<<x<<endl;
G[u].push_back(x); dfs(u,x);
}
} void cir(){
for(int i=1;i<=n;i++) puts("0");
exit(0);
} void find_cir(int x){
for(int i=0;i<G[x].size();++i){
int u=G[x][i];
if(vis[u]) cir();
if(tt[u]) continue;
vis[u]=1; tt[u]=1;
find_cir(u); vis[u]=0;
}
} int main(){
// freopen("in","r",stdin);
n=rd(),m=rd(); int x,y;
for(int i=1;i<n;i++){
x=rd(),y=rd();
v[x].push_back(y);
v[y].push_back(x);
}
dfs1(1,0); dfs2(1,1);
while(m--){
x=rd(),y=rd(); G[x].push_back(y);
// cout<<x<<" "<<y<<endl;
if(id[y]>=id[x] && id[y]<=id[x]+siz[x]-1){
int now=jump(y,dep[x]+1);
tree.update(1,1,n,1,id[now]-1);
tree.update(1,1,n,id[now]+siz[now],n);
G[x].push_back(now);
// cout<<x<<" "<<now<<endl;
for(int i=0;i<v[x].size();i++){
int u=v[x][i];
if(id[u]>=id[now] && id[u]<=id[now]+siz[now]-1) continue;
// cout<<u<<" "<<x<<endl;
G[u].push_back(x); dfs(u,x);
}
}
else{
tree.update(1,1,n,id[x],id[x]+siz[x]-1);
dfs(x,fa[x]);
}
}
for(int i=1;i<=n;i++)
if(!tt[i]) find_cir(i);
for(int i=1;i<=n;i++) {
if(!tree.query(1,1,n,id[i])) puts("1");
else puts("0");
}
return 0;
}


\(T3\)

传送门

解题思路

  神仙题。首先发现对于一个点来说它的答案一定是从自己这个点直接跳下去或者向左右两边分别找到一个点跳下去。考虑区间\([0,L]\),设\(x\)走到\(L\)的概率为\(f(x)\),那么有\(f(x)=\frac{f(x-1)+f(x+1)}{2}\),发现这是个等差数列的形式,又因为\(f(L)=1,f(0)=0\)可以解得\(f(x)=\frac{x}{L}\),那么这个人在某个点往左右两边走时左边到达\(a\)点,右边到达\(b\)点,则他获得的收益为\(V_a \frac{b-i}{b-a}+V_b \frac{i-a}{b-a}\),那么就得到一个暴力的做法,就是枚举左右端点算最大值。但发现这样复杂度太高,考虑如何能快速找到左右两点。如果把它们放到平面直角坐标系上,每个点横坐标设为位置,纵坐标设为该位置的权值。那么画个图带进去可以发现,要求的其实就是两点连线与\(x=i\)之间交点的纵坐标,那么确定这两个点就可以用凸包判断了。就是把凸包找出来,然后对于一个点来说如果它在凸包上,答案就为这个点的纵坐标,否则为它前后两个凸包上的点连线的\(x=i\)时的纵坐标。

代码

#include<bits/stdc++.h>

using namespace std;
const int N=100005;
const double eps=1e-8;
typedef long long LL; int n,stk[N],top;
double a[N]; struct Node{
int x; LL y;
Node(int _x=0,LL _y=0){
x=_x; y=_y;
}
}node[N]; Node operator-(Node A,Node B){
return Node(A.x-B.x,A.y-B.y);
}
inline LL cross(Node A,Node B){
return A.x*B.y-A.y*B.x;
} inline bool check(int x,int y,int z){
return cross((node[y]-node[x]),(node[z]-node[y]))>=eps;
} inline LL calc(int x,int y,int z){
return (node[y].y*(node[z].x-node[x].x)+node[x].y*(node[y].x-node[z].x))/(node[y].x-node[x].x);
} int main(){
scanf("%d",&n); double tmp;
for(int i=1;i<=n;i++) {
node[i].x=i; scanf("%lf",&tmp);
node[i].y=tmp*100000;
}
stk[++top]=0; node[n+1].x=n+1;
for(int i=1;i<=n+1;i++){
while(top>1 && check(stk[top-1],stk[top],i)) top--;
stk[++top]=i;
} int now=1;
for(int i=1;i<=n;i++){
while(stk[now]<i) now++;
if(stk[now]==i) printf("%lld\n",(LL)(node[i].y));
else printf("%lld\n",calc(stk[now-1],stk[now],i));
}
return 0;
}


USACO2018 DEC(Platinum) (树上乱搞,期望+凸包)的更多相关文章

  1. zoj 3820 Building Fire Stations(树上乱搞)

    做同步赛的时候想偏了,状态总是时好时坏.这状态去区域赛果断得GG了. 题目大意:给一棵树.让求出树上两个点,使得别的点到两个点较近的点的距离最大值最小. 赛后用O(n)的算法搞了搞,事实上这道题不算难 ...

  2. BZOJ3573: [Hnoi2014]米特运输(树上乱搞)

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1669  Solved: 1031[Submit][Status][Discuss] Descript ...

  3. CF809E Surprise me!(莫比乌斯反演+Dp(乱搞?))

    题目大意: 给你一棵树,树上的点编号为\(1-n\).选两个点\(i.j\),能得到的得分是\(\phi(a_i*a_j)*dis(i,j)\),其中\(dis(i,j)\)表示\(a\)到\(b\) ...

  4. BZOJ4401:块的计数(乱搞)

    Description 小Y最近从同学那里听说了一个十分牛B的高级数据结构——块状树.听说这种数据结构能在sqrt(N)的时间内维护树上的各种信息,十分的高效.当然,无聊的小Y对这种事情毫无兴趣,只是 ...

  5. 洛谷P5211 [ZJOI2017]字符串(线段树+乱搞)

    题面 传送门 题解 为什么大佬们全都是乱搞的--莫非这就是传说中的暴力能进队,乱搞能AC-- 似乎有位大佬能有纯暴力+玄学优化\(AC\)(不算上\(uoj\)的\(Hack\)数据的话--这要是放到 ...

  6. bzoj 1050: [HAOI2006]旅行comf(codevs.cn 1001 舒适的路线) 快排+并查集乱搞

    没用的话:好像很久没发博客了,主要是懒太蒟找不到水题.我绝对没弃坑...^_^ 还用些话:本文为博主原创文章,若转载请注明原网址和作者. 进入正题: 先pa网址: bzoj :http://www.l ...

  7. BZOJ_2801_[Poi2012]Minimalist Security_dfs树+特判+乱搞

    BZOJ_2801_[Poi2012]Minimalist Security_dfs树+特判+乱搞 Description 给出一个N个顶点.M条边的无向图,边(u,v)有权值w(u,v),顶点i也有 ...

  8. VIJOS1476 旅行规划(树形Dp + DFS暴力乱搞)

    题意: 给出一个树,树上每一条边的边权为 1,求树上所有最长链的点集并. 细节: 可能存在多条最长链!最长链!最长链!重要的事情说三遍 分析: 方法round 1:暴力乱搞Q A Q,边权为正-> ...

  9. [bzoj4796][CERC2016]Key Knocking_乱搞

    Key Knocking bzoj-4796 CERC-2016 题目大意:描述没有题面短系列..题目链接 注释:$1\le n\le 10^5$. 想法: 乱搞稳AC.考试的时候调试信息又一次杀死了 ...

随机推荐

  1. Go语言入门篇-基本数据类型

    一.程序实体与关键字 任何Go语言源码文件都由若干个程序实体组成的.在Go语言中,变量.常量.函数.结构体和接口被统称为“程序实体”,而它们的名字被统称为“标识符”. 标识符可以是任何Unicode编 ...

  2. TS学习笔记----(一)基础类型

    布尔值: boolean let isDone: boolean = false; 数字: number 和JavaScript一样,TS里的所有数字都是浮点数. 支持十进制和十六进制字面量,TS还支 ...

  3. JavaScript Return Object.Type

    var getType = function(obj) { if (obj == null) { return String(obj); } return typeof obj === 'object ...

  4. Luogu P5339 [TJOI2019]唱、跳、rap和篮球

    题目 设\(f_i\)表示从\((a-4i,b-4i,c-4i,d-4i)\)中选\(n-4i\)个排队的方案数. 那么我们可以容斥,答案为\(\sum\limits_{i=0}^{lim}(-1)^ ...

  5. kotlin学习(10)反射

    反射,简单来说,是一种在运行时动态地访问对象属性和方法的方式,而不需要事先确定这些属性是什么. Kotlin反射API:KClass.KCallable.KFunction.KPropperty KC ...

  6. 常用的 Python 标准库都有哪些?

    标准库:os 操作系统,time 时间,random 随机,pymysql 连接数据库,threading 线程,multiprocessing进程,queue 队列. 第三方库:django 和 f ...

  7. Hive常用非交互式命令

    [hadoop@hadoop hive-0.13.1]$ bin/hive -help usage: hive -d,--define <key=value> Variable subsi ...

  8. SEM和SEO的区别?

    https://www.zhihu.com/question/20307058 SEM在营销中扮演的角色:进攻 搜索引擎营销,即SEM(Search Engine Marketing),是基于搜索引擎 ...

  9. Kafka在windows下的配置使用

    Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partition).多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量 ...

  10. ukhj

    SQL解析顺序: 七种Join图: