1104 DAN

D
多打一个0 爆空间 然后就掉50....
A 妹子
计算几何 斜挂了...

万人迷皮皮轩收到了很多妹子的礼物,由于皮皮轩觉得每个妹子都不错,所以将她们礼物
的包装盒都好好保存,但长此以往皮皮轩的房间里都堆不下了,所以只能考虑将一些包装盒

进其他包装盒里节省空间。
方便起见,我们不考虑包装盒的高度和厚度,只考虑包装盒的长宽。
一句话题意:给出两个矩形,问是否可以将一个矩形放在另一个矩形的内部(含边界),多

考试的时候找的条件不是充要条件....
按照面积进行讨论 枚举角度然后看算出来的长和宽是否小于就行了

//
#include<bits/stdc++.h>
using namespace std;
#define GC getchar()
int n,a1,b1,a2,b2;
double eps=0.001111;
inline int R() {
	char t;
	int x=0;
	while(!isdigit(t)) {
		t=GC;
	}
	while(isdigit(t)) {
		x=x*10+t-48;
		t=GC;
	}
	return x;
}
void FIE() {
	freopen("girls.in","r",stdin);
	freopen("girls.out","w",stdout);
}
int main() {
	//FIE();
	n=R();
	while(n--) {
		a1=R();
		b1=R();
		a2=R();
		b2=R();
		if(a1*b1>a2*b2) {
			int fla=0;
			for(double mid=0; (mid<=90)&&(!fla); mid+=0.0005) {
				double c=cos(((double)mid/180*3.14159));
				double s=sin(((double)mid/180*3.14159));
				double  x1=b2*s;
				double 	x2=a2*c;
				double  y1=b2*c;
				double 	y2=a2*s;
				if((((b1-(x1+x2))>=0)&&(a1-(y1+y2))>=0)) {
					puts("Yes");
					fla=1;
					continue;
				}
			}
			if(fla) continue;
			puts("No");
		} else {
			int fla=0;
			for(double mid=0; (mid<=90)&&(!fla); mid+=0.0005) {
				double c=cos(((double)mid/180*3.14159));
				double s=sin(((double)mid/180*3.14159));
				double  x1=b1*s;
				double 	x2=a1*c;
				double  y1=b1*c;
				double 	y2=a1*s;
				if((((b2-(x1+x2))>=0)&&(a2-(y1+y2))>=0)) {
					puts("Yes");
					fla=1;
					continue;
				}
			}
			if(fla) continue;
			puts("No");


		}
	}
}

B
贪心贪错了 还掉了50
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
B 老大
题意同 Dynamite 这道题目 。。。。 我考试的时候巨贪 想贪心去了 .... 做过的题啊...
定义F1[i] 表示离i号根节点最近的未盖点 F2[i] 表示 离i号根节点最近的已被覆盖的点
DP一下即可

//
#include<bits/stdc++.h>
using namespace std;
#define maxnn (int)4e5+10
int las[maxnn],en[maxnn],nex[maxnn],tot;
int n;
int f1[maxnn],f2[maxnn];
#define GC getchar()
inline int R() {
	char t;
	int x=0;
	while(!isdigit(t)) {
		t=GC;
	}
	while(isdigit(t)) {
		x=x*10+t-48;
		t=GC;
	}
	return x;
}
int ans=0;
int size[maxnn];
void add(int a,int b ) {
	en[++tot]=b;
	nex[tot]=las[a];
	las[a]=tot;
}
void TREE_DP(int v,int fa,int mid) {

	for(int i=las[v]; i; i=nex[i]) {
		int u=en[i];
		if(u!=fa) {
			TREE_DP(u,v,mid);
			f1[v]=max(f1[v],f1[u]+1);
			if(f2[u]!=-1) {
				if(f2[v]==-1)
					f2[v]=f2[u]+1;
				else
					f2[v]=min(f2[v],f2[u]+1);
			}
		}
	}
	if((f1[v]>=mid)) {
		ans++;
		f1[v]=-1;
		f2[v]=0;
		return ;
	}
	if(f2[v]>=0)
		if((f1[v]<mid)&&(f1[v]<=(mid-f2[v]))) {
			f1[v]=-1;
			return ;
		}
	if(f1[v]==-1)
	f1[v]=0;
}
int ch(int t) {
	ans=0;
	for(int i=1; i<=n; i++) {
		f1[i]=f2[i]=-1;
	}
	TREE_DP(1,1,t);
	if(f1[1]>=0) ans++;
	return ans;
}
int main() {
	int x,y;
	n=R();
	for(int i=1; i<n; i++) {
		x=R();
		y=R();
		add(x,y);
		add(y,x);
	}
	int l=0,r=10000000;
	while(l<=r) {
		int mid=(l+r)/2;
		if(ch(mid)<=2) {
			r=mid-1;
		} else {
			l=mid+1;
		}
	}
	cout<<l;
}

C 相交
题目描述
一棵大树下有 n 个巢穴,由 n-1 条双向道路连接,任意两个城市均可互相到达。
大树附近有两群蚂蚁,每天早上,第一群蚂蚁会派一只蚂蚁到这棵树下,并在第 a 个巢穴
到 第
b 个巢穴间的最短路径上的每个巢穴留下气味。每天傍晚,第二群蚂蚁会派一只蚂蚁到

棵树下,并侦查第 c 个巢穴到第 d 个巢穴间的最短路径上是否有蚂蚁留下的气味。
每天蚂蚁留下的气味会在当天深夜消失。
输入
第一行一个正整数 n,含义如题所示。
接下来 n-1 行,每行两个正整数 u,v,表示第 u 个巢穴和第 v 个巢穴间有一条双向道路。
接下来一行一个正整数 q,表示天数。
接下来 q 行,每行四个正整数 a,b,c,d,含义如题所示。
输出
q 行,每行一个字符串。
若第二群派出的蚂蚁侦查到蚂蚁留下的气味,则输出” YES” ,否则输出” NO”

解1:
显然用树链剖分+树状数组维护
20min 敲完还不用调试

//
#include<bits/stdc++.h>
using namespace std;
#define maxnn 301000
#define GC getchar()
int n;
int las[maxnn],en[maxnn],nex[maxnn],tot;
int son[maxnn];
int size[maxnn];
int f[maxnn];
int c1[maxnn],c2[maxnn];
int dep[maxnn];
int dfn[maxnn],low[maxnn],vii,topp[maxnn];
void add(int a,int b) {
	en[++tot]=b;
	nex[tot]=las[a];
	las[a]=tot;
}
void dfs1(int v,int fa) {
	dep[v]=dep[fa]+1;
	size[v]=1;
	f[v]=fa;
	int maxson=-1;
	for(int i=las[v]; i; i=nex[i]) {
		int u=en[i];
		if(u!=fa) {
			dfs1(u,v);
			size[v]+=size[u];
			if(size[u]>maxson) {
				son[v]=u;
				maxson=size[u];
			}
		}
	}
}
void dfs2(int v,int fa,int t) {
	topp[v]=t;
	dfn[v]=++vii;
	if(son[v]) {
		dfs2(son[v],v,t);
	}
	for(int i=las[v]; i; i=nex[i]) {
		int u=en[i];
		if(u==fa) continue;
		if(u==son[v]) continue;
		dfs2(u,v,u);
	}
}
inline int R() {
	char t;
	int x=0;
	while(!isdigit(t)) {
		t=GC;
	}
	while(isdigit(t)) {
		x=x*10+t-48;
		t=GC;
	}
	return x;
}
#define lowbit(i) i&(-i)
void aaa(int x,int d) {
	for(int i=x; i<=n+10000; i+=lowbit(i)) {
		c1[i]+=d;
		c2[i]+=x*d;
	}
}
int get(int x) {
	int ans=0;
	for(int i=x; i; i-=lowbit(i)) {
		ans+=c1[i]*(x+1);
		ans-=c2[i];
	}
	return ans;
}
void zadd(int x,int y,int d) {
	while(topp[x]!=topp[y]) {
		if(dep[topp[x]]<dep[topp[y]]) swap(x,y);
		aaa(dfn[topp[x]],d);
		aaa(dfn[x]+1,-d);
		x=f[topp[x]];
	}
	if(dep[x]<dep[y]) swap(x,y);
	aaa(dfn[y],d);
	aaa(dfn[x]+1,-d);
}
bool query(int x,int y) {
	int ans=0;
	while(topp[x]!=topp[y]) {
		if(dep[topp[x]]<dep[topp[y]]) swap(x,y);
		if(get(dfn[x])-get(dfn[topp[x]]-1)) return true;
		x=f[topp[x]];
	}
	if(dep[x]<dep[y]) swap(x,y);
	if(get(dfn[x])-get(dfn[y]-1)) return true;
	return false;
}
void FIE()
{
	freopen("inter.in","r",stdin);
	freopen("inter.out","w",stdout);
}
int main() {
	//FIE();
	n=R();
	int x,y;
	for(int i=1; i<n; i++) {
		x=R();
		y=R();
		add(x,y);
		add(y,x);
	}
	dfs1(1,1);
	dfs2(1,1,1);
	int q;
	q=R();
	int a,b,c,d;
	while(q--) {
		a=R();
		b=R();
		c=R();
		d=R();
		zadd(a,b,1);
		if(query(c,d)) {
			puts("YES");
		} else {
			puts("NO");
		}
		zadd(a,b,-1);
	}
}

解2 注意到两条链是否有相交的充要条件是一条链的LCA 在 另一条lian 的路径上 然后我们求端点到LCA 的路径长度 是否等于 端点的长度就行了


N 230pts
A 方差
展开柿子就行了 5min 搞完 注意快读的时候 要判断负数
B 分糖果
遇到困难应该想到熔池
定义f[i]表示前i的不相同的方案数
则柿子可熔池为 \(f[i]=\sum_j f[j]*min(a[j+1...i])*{(-1)^{i-j-1}}\)
考虑链转环 利用转环的方式 将首尾相同的方案贡献算出来就行了 注意利用单调zhan 优化
时间复杂度 O(n)

//
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
#define maxnn 10000000
ll n,a[maxnn];
ll f[maxnn];
ll mi=1000000000;
ll pos;
ll sum[maxnn];
struct node {
	ll l,r,v,s;
};
stack<node> Q;
int main() {
	
  //	freopen("data.in","r",stdin);
  	//	freopen("myp.out","w",stdout);
	ll ans=0;
	cin>>n;
	for(int i=1; i<=n; i++) {
		scanf("%lld",&a[i]);
		if(a[i]<mi) {
			mi=a[i];
			pos=i;
		}
		a[i+n]=a[i];
	}
	for(int i=1; i<=n; i++) {
		a[i]=a[pos+i-1];
	}
	ll tot=mod-a[1];
	for(int i=1; i<=n; i++) {
		if(i&1) f[i]=(((f[i]-tot)%mod+mod))%mod;
		else f[i]=(((f[i]+tot)%mod+mod))%mod;
	
		sum[i]=sum[i-1];
		if(i&1) sum[i]=((sum[i]+f[i])%mod+mod)%mod;
		else sum[i]=((sum[i]-f[i])%mod+mod)%mod;
		int l=i-1;
		while(Q.size()&&(Q.top().v>a[i+1])) {
			tot=((tot-Q.top().s)%mod+mod)%mod;
			Q.pop();
			if(Q.size())
			l=Q.top().r;
			else
			{
				l=0;
			}
		}
		ll s=(((sum[i]-sum[l])*a[i+1])%mod+mod)%mod;
		Q.push(node {l+1,i,a[i+1],s});
		tot=((tot+s)%mod+mod)%mod;
	}
	for(int i=2; i<=n; i++) {
		if((n-i)&1) ans=((ans-f[i])%mod+mod)%mod;
		else ans=((ans+f[i])%mod+mod)%mod;
	}
	cout<<(ans%mod+mod)%mod;
}

C
题目描述
给定一张n个点m 条边的无向图,现在想要把这张图定向。
有 p个限制条件,每个条件形如(x,y) ,表示在新的有向图当中, x要能够沿
着一些边走到 y。
现在请你求出,每条边的方向是否能够唯一确定。同时请给出这些能够唯一确定
的边的方向
解:
tarjan 求边双联通分量缩点搞成一个森林 然后差分就行了
注意判断连通性

//
#include<bits/stdc++.h>
using namespace std;
#define maxnn (int)(2e5+10)
int belong[maxnn];
int dfn[maxnn],low[maxnn];
int vii;
int scc;
int vis[maxnn];
int dep[maxnn];
int f[maxnn][20];
int fff[maxnn];
int gf(int v) {
	return fff[v]==v?v:fff[v]=gf(fff[v]);
}
int cnt1[maxnn],cnt2[maxnn];
int tot=1,nex[maxnn],las[maxnn],en[maxnn];
int ztot,znex[maxnn],zlas[maxnn],zen[maxnn];
#define GC getchar()
inline int R() {
	int f=1;
	int x=0;
	char t;
	t=GC;
	while(!isdigit(t)) {
		if(t=='-') {
			f=-1;
		}
		t=GC;
	}
	while(isdigit(t)) {
		x=x*10+t-48;
		t=GC;
	}
	return x*f;
}
struct node {
	int st,en;
} ed[maxnn];
int cnt;
int n,m;
void add(int a,int b) {
	en[++tot]=b;
	nex[tot]=las[a];
	las[a]=tot;
}
void zadd(int a,int b) {
	zen[++ztot]=b;
	znex[ztot]=zlas[a];
	zlas[a]=ztot;
}
stack<int > Q;
void tarjan(int v,int e) {
	Q.push(v);
	dfn[v]=low[v]=++vii;
	for(int i=las[v]; i; i=nex[i]) {
		if((e!=-1)&&((i^1)==e)) continue;
		int u=en[i];
		if(!dfn[u]) {
			tarjan(u,i);
			low[v]=min(low[u],low[v]);
		} else {
			low[v]=min(low[v],dfn[u]);
		}
	}
	int r;
	if(low[v]==dfn[v]) {
		scc++;
		do {
			r=Q.top();
			Q.pop();
			belong[r]=scc;
		} while(r!=v);
	}
}
int goup(int x,int k) {
	int s=log2(n);
	for(int i=s; i>=0; i--) {
		if((1<<i)&k) {
			x=f[x][i];
		}
	}
	return x;
}
int lca(int x,int y) {
	if(dep[x]<dep[y]) swap(x,y);
	x=goup(x,dep[x]-dep[y]);
	if(x==y) return x;
	int s=log2(n);
	for(int i=s; i>=0; i--) {
		if(f[x][i]!=f[y][i]) {
			x=f[x][i];
			y=f[y][i];
		}
	}
	return f[x][0];
}
void dfs(int v,int fa) {
	vis[v]=1;
	dep[v]=dep[fa]+1;
	f[v][0]=fa;
	int s=log2(n);
	for(int i=1; i<=s; i++) {
		f[v][i]=f[f[v][i-1]][i-1];
	}
	for(int i=zlas[v]; i; i=znex[i]) {
		int u=zen[i];
		if(u!=fa) {
			dfs(u,v);
		}
	}
}
void dfs2(int v,int fa) {
	vis[v]=1;
	for(int i=zlas[v]; i; i=znex[i]) {
		int u=zen[i];
		if(u!=fa) {
			dfs2(u,v);
			cnt1[v]+=cnt1[u];
			cnt2[v]+=cnt2[u];
		}
	}
}
int main() {
	//freopen("c.in","r",stdin);
	//freopen("c.out","w",stdout);
	int x,y;
	n=R();
	m=R();
	for(int i=1; i<=m; i++) {
		ed[++cnt].st=R();
		ed[cnt].en=R();
		add(ed[cnt].st,ed[cnt].en);
		add(ed[cnt].en,ed[cnt].st);
	}
	for(int i=1; i<=n; i++) {
		if(!dfn[i]) tarjan(i,-1);
	}
	for(int i=1; i<=n; i++) {
		fff[i]=i;
	}
	for(int i=1; i<=n; i++) {
		for(int j=las[i]; j; j=nex[j]) {
			int u=en[j];
			if(belong[u]==belong[i]) {
				continue;
			}
			zadd(belong[i],belong[u]);
			int fx=gf(belong[i]);
			int fy=gf(belong[u]);
			if(fx==fy) continue;
			fff[fx]=fy;
		}
	}
	for(int i=1; i<=n; i++)
	if(!vis[belong[i]])
	dfs(belong[i],belong[i]);
	for(int i=1; i<=n; i++)
		vis[i]=0;
	int q;
	q=R();
	while(q--) {
		x=R();
		y=R();
		x=belong[x];
		y=belong[y];
		if(gf(x)!=gf(y)) continue;
		int d=lca(x,y);
		cnt1[x]++;
		cnt1[d]--;
		cnt2[y]++;
		cnt2[d]--;
	}
	for(int i=1; i<=n; i++)
		if(!vis[belong[i]])
		    dfs2(belong[i],belong[i]);
	for(int i=1; i<=cnt; i++) {
		if(belong[ed[i].st]==belong[ed[i].en]) {
			putchar('B');
			continue;
		}
		if(f[belong[ed[i].st]][0]==belong[ed[i].en]) {
			if(cnt1[belong[ed[i].st]]) {
				putchar('R');
				continue;
			}
			if(cnt2[belong[ed[i].st]]) {
				putchar('L');
				continue;
			}
		}
		if(f[belong[ed[i].en]][0]==belong[ed[i].st]) {
			if(cnt1[belong[ed[i].en]]) {
				putchar('L');
				continue;
			}
			if(cnt2[belong[ed[i].en]]) {
				putchar('R');
				continue;
			}
		}
		putchar('B');
	}
}

posted @ 2019-11-04 14:54  ALEZ  阅读(149)  评论(0编辑  收藏  举报