• 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');
    	}
    }
    
    
  • 相关阅读:
    医院科室管理系统日志实现
    遍历hashmap
    java用于控制可见性的4个访问修饰符
    java中error和exception
    线程的状态
    线程间的通信
    位运算(1的个数;2.判断奇偶)
    24点组合
    Sequential 类的设备迁移
    gluon多线程迭代器
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11792065.html
Copyright © 2020-2023  润新知