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;
}


 

你可能感兴趣的:(2012中南大学校赛D题 - 很好的思维题...)