2012中南大学校赛D题 - 很好的思维题...

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1163

      这题首先提醒的是做除法再模一个数..分子分母分别模了后再相除是得不到正确结果的...开始这题纠结了很久..想了同余方程..甚至讨论了线段树...最后想通了还是So eazy的,

      由于乘法是可以分别取模再相乘的...本题的方法和经典DP问题合唱队形差不多...算出从第一个数开始一路乘到每个数的值和每个数一路乘到最后一个数的值..这两个过程都是O(n)的..正扫一遍..反扫一遍就ok了...然后...就不用说了吧...

      CSU的OJ真是奇葩...是定义long long....格式控制用%lld....PE了好几次....

 

Program:

#include<iostream>
#include<stdio.h>
#define ll long long
using namespace std;
ll n,m,s[100005],a[100005],b[100005],ans[100005];
int main()
{
      int i;
      while (~scanf("%lld%lld",&n,&m))
      {
            for (i=1;i<=n;i++) scanf("%lld",&s[i]);
            a[0]=a[n+1]=b[0]=b[n+1]=s[0]=s[n+1]=1;
            for (i=1;i<=n;i++) a[i]=(s[i]*a[i-1])%m;
            for (i=n;i>=1;i--) b[i]=(s[i]*b[i+1])%m;
            for (i=1;i<=n;i++) 
            {
                  if (s[i]==0) ans[i]==1;
                  else ans[i]=(a[i-1]*b[i+1])%m;
            } 
            printf("%lld",ans[1]);
            for (i=2;i<=n;i++) printf(" %lld",ans[i]);
            printf("\n");
      }
      return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值