2015 ACM/ICPC Asia Regional Shanghai Online

18 篇文章 0 订阅
11 篇文章 0 订阅

1008 An easy problem


解题思路:一颗线段树单点更新后求乘积。


#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<ctime>
#define LL long long
#define db double
#define EPS 1e-15
#define inf 1e16
#define pa pair<int,int>

using namespace std;

const int maxn=155555;
LL sum[maxn*4+4];
int add;
int a[maxn];
int L,R;
int MOD;
int p;
void pushup(int rt){
    sum[rt]=sum[rt<<1]*sum[rt<<1|1]%MOD;
}
void build(int l,int r,int x){
	if (l==r){
		sum[x]=1;
		return ;
	}
	int m=(l+r)>>1;
	build(l,m,x<<1);
	build(m+1,r,x<<1|1);
	pushup(x);
}
void update(int l,int r,int x){
	if (l==r){
		sum[x]=add;
		return ;
	}
	int mid=(l+r)>>1;
	if (p<=mid) update(l,mid,x<<1);
	else update(mid+1,r,x<<1|1);
	pushup(x);
}
LL query(int l,int r,int x){
	LL ret=1;
	if (L<=l && r<=R) return sum[x];
	int mid=(l+r)>>1;
	if (L<=mid) ret*=query(l,mid,x<<1)%MOD;
	if (R>mid) ret*=query(mid+1,r,x<<1|1)%MOD;
	return ret%MOD;
}
int main(){
	int T,o=0;
	scanf("%d",&T);
	while (T--){
        int q;
		printf("Case #%d:\n",++o);
		scanf("%d%d",&q,&MOD);
		build(1,q,1);
		for (int i=1;i<=q;i++){
			int op,u;
			scanf("%d%d",&op,&u);
			if (op==1){
				p=i; add=u;
				update(1,q,1);
				L=1,R=i;
				printf("%I64d\n",query(1,q,1)%MOD);
			}
			else {
				p=u; add=1;
				update(1,q,1);
				L=1; R=i;
				printf("%I64d\n",query(1,q,1)%MOD);
			}
		}
	}
	return 0;
}


1009  Explore Track of Point

解题思路:依靠脑洞我们可以得出这个轨迹是一条过等腰三角形内心和两个底点的弧,然后利用初中几何知识计算即可。

证明见此处  http://blog.csdn.net/Baileys0530/article/details/48753151

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<ctime>
#define LL long long
#define db double
#define EPS 1e-15
#define inf 1e16
#define pa pair<int,int>

using namespace std;

struct node{
	db x,y;
}A,B,C,M;
db dis(node a,node b){
	return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));
}
int main(){
	int T,o=0;
	scanf("%d",&T);
	while (T--){
		scanf("%lf%lf%lf%lf%lf%lf", &A.x, &A.y, &B.x, &B.y, &C.x, &C.y);
		M.x=(B.x+C.x)/2, M.y=(B.y+C.y)/2;
		db a=dis(B,C)/2, b=dis(A,B), h=dis(A,M);
		db r=a*h/(a+b);
		db R=(a*a-r*r)/r/2+r;
		db ans=(2*R)*asin(a/R);
		ans+=h;
		printf("Case #%d: %.4f\n",++o,ans);
	}
	return 0;
}

1010 A Sweet Journey

解题思路:对每一段遇到沼泽之前积累的体力值和走过沼泽浪费的体力值,如果小于0则提前积累出相应的体力,对每段都这样计算。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<ctime>
#define LL long long
#define db double
#define EPS 1e-1
#define inf 1e16
#define pa pair<int,int>

using namespace std;
#define maxn 100010  
int l[maxn],r[maxn];  
int main(){
	int T,jj=1;
	scanf("%d",&T);
	while (T--){
		int n,A,B,L;  
        scanf("%d%d%d%d",&n,&A,&B,&L);
		memset(l,0,sizeof(l));
		memset(r,0,sizeof(r));
		for (int i=1;i<=n;i++){
			scanf("%d%d",&l[i],&r[i]);
		}
		int ans=0,res=0;
		ans+=(l[1]-0)*B-(r[1]-l[1])*A;
		if(ans<0) res+=fabs(ans),ans=0;  
        for(int i=2;i<=n;i++){  
            ans+=(l[i]-r[i-1])*B-(r[i]-l[i])*A;  
            if(ans<0) res+=fabs(ans),ans=0;  
        }  
        printf("Case #%d: %d\n",jj++,res); 
	}
}


1011  Can you find it

给定 C,k1, b1, k2 找出所有的(a, b)满足  ak1n+b1 bk2nk2+1  = 0 (mod C)(n = 1, 2, 3, ...)  (1<=a, b <C)。

解题思路:把n取1和2,得到两个式子,上下除一除,猜一猜,得到b^(k2) = a^(k1),验证即可。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<ctime>
#define LL long long
#define db double
#define EPS 1e-1
#define inf 1e16
#define pa pair<int,int>

using namespace std;

LL pow_mod(int a,int n,int mod){
    if (n==0) return 1;
    LL x=pow_mod(a,n/2,mod);
    LL ans=(LL)x*x%mod;
    if (n%2==1) ans=ans*a%mod;
    return ans;
}
int main(){
    int b1,k1,k2,mod;
    int cas=1;
    while (scanf("%d%d%d%d",&mod,&k1,&b1,&k2)!=EOF){
        printf("Case #%d:\n",cas++);
        bool flag=false;
        for (int i=1;i<mod;i++){
            LL tmp=pow_mod(i,k1+b1,mod);
            int b=mod-tmp;
            LL tta=pow_mod(i,k1,mod);
            LL ttb=pow_mod(b,k2,mod);
            if (tta==ttb){
                flag=true;
                printf("%d %d\n",i,b);
            }
        }
        if (!flag) printf("-1\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值