题目链接:HDU 5475
题目大意:
一个数从1开始,有两种操作,1. 将这个数乘 y (0<y< 1e9 ) 2.将这个数除以第 n个操作数的 y,题目保证第n个操作一定是第1种操作。
操作次数最多 1e5 。每次操作后输出 当前的数%m
解题步骤:
看题目通过率就知道很多人开始和我想得一样, 每次乘除之后取余。结果wa掉。后来仔细一想,题目要求的是输出的时候,输出这个数取模后的值,并没让这个数取模, 而且如果在1操作后保留取模后的值, 那么2操作的除法操作就会有错误。
想到这,就开始敲 JAVA大数了,提交T LE ,又试了一下 C++大数模拟 TLE 。。。
这时候脑子就开始胡思乱想了。
想到一个暴力的方法,每次乘法边乘边取模,遇到除法就从头更新一下(标记的位置不用再乘)。然而操作次数高达1e5, 就被否决了。
然后就是奇思妙想了,是不是DP? 还是哪种高深的数据结构?
今天百度了一下 发现暴力居然能过!暴力居然能过!居然能过!
暴力出奇迹啊! 其实这样的题目就应该果断来一发的!
当然网上也有线段树的做法。
源代码:
纯暴力代码 Exe.Time 3354MS
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<stack>
#include<vector>
using namespace std;
const int maxn = 100000 + 10;
typedef unsigned long long ll;
ll num[maxn];
struct node{
ll a,b;
}no[maxn];
int qe[maxn];
bool vis[maxn];
int main(){
int t;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++){
printf("Case #%d:\n",cas);
int q,mod;
memset(vis,0,sizeof(vis));
scanf("%d%d",&q,&mod);
int a;
long long ans = 1;
for(int i=1;i<=q;i++){
scanf("%d%d",&a,&qe[i]);
if(a == 2){
vis[i] = true;
vis[qe[i]] = true; //标记不用乘的位置。
ans = 1; 遇到 2 就从头更新一遍。。。
for(int j=1;j<i;j++){
if(!vis[j]){
ans=ans*qe[j];
ans%=mod;
}
}
}
else{
ans=ans*qe[i];
ans%=mod;
}
printf("%lld\n",ans);
}
}
return 0;
}
稍微优化的暴力代码 Exe.Time 2246MS
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<stack>
#include<vector>
using namespace std;
const int maxn = 100000 + 10;
typedef unsigned long long ll;
ll num[maxn];
struct node{
ll a,b;
}no[maxn];
int qe[maxn];
bool vis[maxn];
long long x[maxn]; 用x储存当前的结果
int main(){
int t;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++){
printf("Case #%d:\n",cas);
int q,mod;
memset(vis,0,sizeof(vis));
scanf("%d%d",&q,&mod);
int a;
long long ans = 1;
x[0] = 1;
for(int i=1;i<=q;i++){
scanf("%d%d",&a,&qe[i]);
if(a == 2){
vis[i] = true;
vis[qe[i]] = true;
for(int j=qe[i];j<=i;j++){ 与纯暴力代码不同,从修改的位置开始更新到当前的i
x[j] = x[j-1];
if(vis[j])
continue;
x[j] = x[j]*qe[j];
x[j] = x[j]%mod;
}
}
else{
x[i] = x[i-1]*qe[i];
x[i]=x[i]%mod;
}
printf("%lld\n",x[i]);
}
}
return 0;
}