2019牛客多校第一场 A,B,C,E,F,H,I,J

A-Equivalent Prefixes

题目链接:https://ac.nowcoder.com/acm/contest/881/A

题目大意:给出两个数组,分别包含n个数字。定义RMQ(u,l,r)=RMQ(v,l,r)是数组u和v在同样的[l,r]区间,最小值的位置是一样的。找到一个P满足所有的1<=l<=r<=P满足RMQ(u,l,r,)=RMQ(v,l,r);

思路:对于每个数字,找到它在数组中的影响区间(在这个区间内他就是最小的),可用二分找到。然后从1开始,对于每个数字,判断是否能够被选中,要求所覆盖的区间重合,如果覆盖区间不重合,则右边取最小的那个(刷新上界)。直到到达上界位置。

注意些RMQ问题的时候不要用线段树,因为线段树查询longn,也是一笔不小的开支,用ST表就好了。我线段树的T掉了(当然大佬如果用更好的方法能过当我在瞎说)200ms+。

文少读题大喘气,给我说了三次题意,WA了6发,哭了。

ACCode:

#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
// srand(unsigned)time(NULL));rand();
 
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
 
#define ll long long
#define Pair pair<int,int>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
 
const int MAXN=1e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=998244353;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)

class STtable{
	int STmax[MAXN][20],STmin[MAXN][20],mn[MAXN];
	
	public : void IntST(int n,int a[]){
		mn[0]=-1;
		for(int i=1;i<=n;++i){
			mn[i]=((i&(i-1))==0)?mn[i-1]+1:mn[i-1];
			STmax[i][0]=STmin[i][0]=a[i];
		}
		for(int j=1;j<=mn[n];++j){
			for(int i=1;i+(1<<j)-1<=n;++i){
				STmax[i][j]=max(STmax[i][j-1],STmax[i+(1<<(j-1))][j-1]);
				STmin[i][j]=min(STmin[i][j-1],STmin[i+(1<<(j-1))][j-1]);
			}
		}
	}
	public : int RMQMAX(int l,int r){
		int k=mn[r-l+1];
		return max(STmax[l][k],STmax[r-(1<<k)+1][k]);
	}
	public : int RMQMIN(int l,int r){
		int k=mn[r-l+1];
		return min(STmin[l][k],STmin[r-(1<<k)+1][k]);
	}
};
STtable STA,STB;
int A[MAXN],B[MAXN];
int InterA[MAXN][2],InterB[MAXN][2];
int n,m;

int main(){
	while(~scanf("%d",&n)){
		for(int i=1;i<=n;++i) scanf("%d",&A[i]);
		for(int i=1;i<=n;++i) scanf("%d",&B[i]);
		STA.IntST(n,A);STB.IntST(n,B);
		for(int i=1;i<=n;++i){//找到每个点的有效区间 
			int l=1,r=i,mid;
			while(l<=r){//找到最左边的有效区间 
				mid=(l+r)>>1;
				if(STA.RMQMIN(mid,i)==A[i]) r=mid-1;
				else l=mid+1;
			}InterA[i][0]=l;
			l=i,r=n;
			while(l<=r){//找最右边的有效区间 
				mid=(l+r)>>1;
				if(STA.RMQMIN(i,mid)==A[i]) l=mid+1;
				else r=mid-1;
			}InterA[i][1]=r;
		}
		for(int i=1;i<=n;++i){//找到每个点的有效区间 
			int l=1,r=i,mid;
			while(l<=r){//找到最左边的有效区间 
				mid=(l+r)>>1;
				if(STB.RMQMIN(mid,i)==B[i]) r=mid-1;
				else l=mid+1;
			}InterB[i][0]=l;
			l=i,r=n;
			while(l<=r){//找最右边的有效区间 
				mid=(l+r)>>1;
				if(STB.RMQMIN(i,mid)==B[i]) l=mid+1;
				else r=mid-1;
			}InterB[i][1]=r;
		}
//		printf("A:");for(int i=1;i<=n;++i) printf("i=%d l=%d r=%d\n",i,InterA[i][0],InterA[i][1]);
//		printf("B:");for(int i=1;i<=n;++i) printf("i=%d l=%d r=%d\n",i,InterB[i][0],InterB[i][1]);
		int maxr=n,p=1;
		for(int i=1;i<=n;++i){
			if(InterA[i][0]==InterB[i][0]){
				int tempr;
				if(InterA[i][1]==InterB[i][1]){//符合区间 
					p=i;
				}
				else{
					tempr=min(InterA[i][1],InterB[i][1]);
					if(tempr>maxr) break;
					else maxr=tempr;
				}p=i;
			}
			else break;
		}printf("%d\n",p);
	}
}

B-Integration

题目链接:https://ac.nowcoder.com/acm/contest/881/B

题目大意:给出一个公式,求另一个公式。

思路:由给出的公式求出单项的答案后,手写n=2,3,4化简找规律。

下面给出步骤:

\int_{0}^{\infty} \frac{1}{1+x^2}dx=\frac{\pi }{2}

=>\int_{0}^{\infty} \frac{1}{a^2+x^2}dx=\frac{1}{a^2}\int_{0}^{\infty} \frac{1}{1+\frac{x^2}{a^2}}dx=\frac{1}{a}\int_{0}^{\infty} \frac{1}{1+\frac{x^2}{a^2}}d_(\frac{x}{a})=\frac{\pi}{2a}

得出单独的一项:\int_{0}^{\infty} \frac{1}{a^2+x^2}dx=\frac{\pi}{2a}

对于\frac{1}{\pi}\int_{0}^{\infty} \frac{1}{\prod_{i=1}^{n}(a_i^2+x^2)}dx拆开。举特例:

\frac{1}{\pi}\int_{0}^{\infty} \frac{1}{\prod_{i=1}^{n}(a_i^2+x^2)}dx=\frac{1}{\pi}\int_{0}^{\infty} \frac{1}{(a_1^2+x^2)*(a_2^2+x^2)*(a_3^2+x^2)....(a_n^2+x^2)}dx

当n=2时:

原式=\frac{1}{\pi}\int_{0}^{\infty} \frac{1}{(a_1^2+x^2)*(a_2^2+x^2)}dx=(裂项相消)\frac{1}{\pi}\int_{0}^{\infty} \frac{1}{a_2^2-a_1^2}*(\frac{1}{(a_1^2+x^2)}-\frac{1}{(a_2^2+x^2)})dx

=\frac{1}{\pi}(\frac{1}{a_2^2-a_1^2}\int_{0}^{\infty}\frac{1}{(a_1^2+x^2)}dx + \frac{1}{a_1^2-a_2^2}\int_{0}^{\infty}\frac{1}{(a_2^2+x^2)}dx)

前面的\frac{1}{\pi}对后面的式子没有影响,忽略掉:\frac{1}{a_2^2-a_1^2}\int_{0}^{\infty}\frac{1}{(a_1^2+x^2)}dx + \frac{1}{a_1^2-a_2^2}\int_{0}^{\infty}\frac{1}{(a_2^2+x^2)}dx

当n=3时:

原式=\frac{1}{\pi}\int_{0}^{\infty} \frac{1}{(a_1^2+x^2)*(a_2^2+x^2)*(a_3^2+x^2)}dx=(裂项相消)\frac{1}{\pi}\int_{0}^{\infty} \frac{1}{a_2^2-a_1^2}*(\frac{1}{(a_1^2+x^2)}-\frac{1}{(a_2^2+x^2)})*(a_3^2-a_1^2)dx

=\frac{1}{\pi}\int_{0}^{\infty} \frac{1}{a_2^2-a_1^2}*(\frac{1}{(a_1^2+x^2)*(a_3^2-a_1^2)}-\frac{1}{(a_2^2+x^2)*(a_3^2-a_1^2)})dx=

\frac{1}{\pi}\int_{0}^{\infty}\frac{1}{a_2^2-a_1^2}*(\frac{1}{a_3^2-a_1^2}*(\frac{1}{a_1^2+x^2}-\frac{1}{a_3^2+x^2})-\frac{1}{a_3^2-a_2^2}*(\frac{1}{a_2^2+x^2}-\frac{1}{a_3^2+x^2})dx

=\frac{1}{\pi}\int_{0}^{\infty}\frac{1}{(a_2^2-a_1^2)(a_3^2-a_1^2)}*\frac{1}{a_1^2+x^2}+\frac{1}{(a_1^2-a_2^2)(a_3^2-a_2^2)}*\frac{1}{a_2^2+x^2}+\frac{1}{(a_3^2-a_2^2)(a_3^2-a_1^2)}*\frac{1}{a_3^2+x^2}

比较n=3和n=2容易发现通项公式:\frac{1}{\pi}\sum_{i=1}^{n}\prod_{j=1,j!=i}^{n}\frac{1}{a_j^2-a_i^2}\int_{0}^{\infty} \frac{1}{a_i^2+x^2}dx

带入上面得到的单项式子:\sum_{i=1}^{n}\prod_{j=1,j!=i}^{n}\frac{1}{2*(a_j^2-a_i^2)*a_i}

然后就是n^2跑答案了。

ACCode:

#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
// srand(unsigned)time(NULL));rand();
 
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
 
#define ll long long
#define Pair pair<int,int>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
 
const int MAXN=1e3+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)

ll A[MAXN];
int n;

ll Inv(ll a,ll n){
	ll res=1;
	while(n){
		if(n&1) res=res*a%MOD;
		a=a*a%MOD;
		n>>=1;
	}return res;
}
int main(){
	while(~scanf("%d",&n)){
		for(int i=1;i<=n;++i){
			scanf("%lld",&A[i]);
		}
		ll Ans=0;
		for(int i=1;i<=n;++i){
			ll Res=2*A[i];
			for(int j=1;j<=n;++j){
				if(j==i) continue;
				Res=Res*(A[j]*A[j]%MOD-A[i]*A[i]%MOD+MOD)%MOD;
			}
			Ans=(Ans+Inv(Res,MOD-2))%MOD;
		}
		printf("%lld\n",Ans);
	}
}

C-Euclidean Distance

题目链接:https://ac.nowcoder.com/acm/contest/881/C

数学队友的:https://blog.csdn.net/henucm/article/details/96836348

E-ABBA

题目链接:https://ac.nowcoder.com/acm/contest/881/E

题目大意:给出2(n+m)长度的字符串,问能有多少种方法构成n个AB和m个BA。

思路:前缀和+DP(文少牛逼)文少上来就A掉了这道题:https://blog.csdn.net/henu_1710252529/article/details/96467385

ACCode:文少的代码,在他博客里。

F-Random Point in Triangle

题目链接:https://ac.nowcoder.com/acm/contest/881/F

题目大意:给出三个点,找出三点组成三角形内一点p满足E的期望:36*E。

思路:可以猜出来的。但是既然写出了博客,那就证明出来吧:

由于求最大的三角形的面积。因为三角形在重心处三个面积相等。那么我们只考虑一个就好了。

首先直到一个概念:三角形的E(h)=重心。高的期望是重心所在的位置.

设三角形的高为h。

看图,三角形PBC在p在深绿色区域内是满足最大面积的。所以P{P落在ADE范围内}:P{P落在ODE范围内}=3:1(易证)。

所以E(S\DeltaPBC(DE上))=1/2BC(2/3h);E(S\DeltaPBC(DE下))=1/2BC(1\2h-1/2  *1/3 *1/3h)=1/2BC(4/9h)

所以:E(S\DeltaPBC)=3/4 * 1/3BCh+1/4 * 2/9BCh=11/36BCh=11/36 * 2*S\DeltaPBC.

因此直接输出11*(BC叉乘BA)即可。

ACCode:

#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
// srand(unsigned)time(NULL));rand();
 
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
 
#define ll long long
#define Pair pair<int,int>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
 
const int MAXN=1e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=998244353;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)

struct Point{
	ll x,y;
	Point(ll _x=0,ll _y=0){
		x=_x;y=_y;
	}
	friend Point operator + (Point a,Point b){
		return Point(a.x+b.x,a.y+b.y);
	}
	friend Point operator * (ll x,Point a){
		return Point(x*a.x,x*a.y);
	}
	friend ll operator ^ (Point a,Point b){
		return abs(a.x*b.y-a.y*b.x);
	}
	friend Point operator - (Point a,Point b){
		return Point(a.x-b.x,a.y-b.y);
	}
};

int main(){
	Point A,B,C;
	while(~scanf("%lld%lld%lld%lld%lld%lld",&A.x,&A.y,&B.x,&B.y,&C.x,&C.y)){
		ll S=((B-A)^(C-A));
		if(S==0){
			printf("0\n");
			continue;
		}
		printf("%lld\n",S*11);
	}
}

H-XOR

题目链接:https://ac.nowcoder.com/acm/contest/881/H

数论队友线性基:https://blog.csdn.net/henucm/article/details/99285575

I-Points Division

题目链接:https://ac.nowcoder.com/acm/contest/881/I

题目大意:给出n个点,每个点都有两个属性a,b。找出一条折线,满足折线上的点之和a=折线下的点之和b。

文少用的线段树优化DP。本来他想让我写,结果我甩给了他一个线段树板子,就让它自己写了。。

题解:https://blog.csdn.net/henu_1710252529/article/details/100087766

J-Fraction Comparision

题目链接:https://ac.nowcoder.com/acm/contest/881/J

题目大意:给出四个数,比较他们的大小。

思路:Java大数牛逼!文少上去秒A。

ACCode:

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in =new Scanner(System.in);
        String x1;
        while(in.hasNext()){
            x1=in.next();
            BigInteger x=new BigInteger(x1);
            x1=in.next();
            BigInteger a=new BigInteger(x1);
            x1=in.next();
            BigInteger y=new BigInteger(x1);
            x1=in.next();
            BigInteger b=new BigInteger(x1);
            x=x.multiply(b);
            y=y.multiply(a);
            if(x.compareTo(y)==0){
                System.out.println("=");
            }else if(x.compareTo(y)==1){
                System.out.println(">");
            }else if(x.compareTo(y)==-1){
                System.out.println("<");
            }
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值