昊昊爱运动 n^2的预处理 or 前缀和
Source
第七届ACM趣味程序设计竞赛第二场(正式赛) A
My Solution
1、当时把时间改成3000MS
所以直接暴力,过去,用一个数字cot[108],来记录每个区间内的任务是否在区间类出现过。
现在时间突然该回来了,所以 嘿嘿,我只是记录一下自己的代码☺☺
☺☺
☺☺
☺☺
☺☺
#include
#include
#include
#define LOCAL
using namespace std;
int n[2008],cot[108];
int main()
{
#ifdef LOCAL
freopen("a.txt","r",stdin);
#endif // LOCAL
int N,M,Q,x,y,cott;
scanf("%d%d",&N,&M);
for(int i=1;i<=N;i++){
scanf("%d",&n[i]);
}
scanf("%d",&Q);
while(Q--){
cott=0;
memset(cot,0,sizeof(cot));
scanf("%d%d",&x,&y);
for(int i=x;i<=y;i++)
if(cot[n[i]]==0) {cott++;cot[n[i]]++;}
//for(int j=0;j<=M;j++)
// if(cot[j]!=0) ;
printf("%d",cott);
if(Q) printf("n");
}
return 0;
}
2、用n^2的预处理,直接搞出ans[i][j],然后O(1)的询问
当时2000的平方算成1e8级了,☺☺,事实上是1e6级。
#include
#include
//#define LOCAL
using namespace std;
const int maxn=2000+2;
int n[maxn],cot[108],ans[maxn][maxn];
int main()
{
#ifdef LOCAL
freopen("a.txt","r",stdin);
#endif // LOCAL
int N,M,Q,x,y,cott;
scanf("%d%d",&N,&M);
for(int i=1;i<=N;i++){
scanf("%d",&n[i]);
}
//ans[maxn][maxn]就不用memset了,由于这里没有必要,而且数组比较大,memset起来还是要耗点时间的
//n^2的预处理
for(int i=1;i<=N;i++){
memset(cot,0,sizeof(cot));cott=0;
for(int j=i;j<=N;j++){
if(cot[n[j]]==0) {cott++;cot[n[j]]++;}
ans[i][j]=cott;//由于这里指的是[x,y],且1<=x,所以上面要用 int i=1;i<=N;i++,下面j也是
} //数组和所需要对应好
}
//询问
scanf("%d",&Q);
while(Q--){
scanf("%d%d",&x,&y);
printf("%d",ans[x][y]);
if(Q) printf("n");
}
return 0;
}
3、前缀和思想
在输入的时候直接维护ans[ i ][ j ],表示在[1,i ]中j 出现了多少次,维护的时候注意把前一个的所有信息都要维护的这一项;
然后每次询问扫M,判断ans[ y ][ i ]-ans[ x-1 ][ i ]是否大于0 。用cott计数;
#include
#include
#define LOCAL
using namespace std;
int ans[2002][108];
int main()
{
#ifdef LOCAL
freopen("a.txt","r",stdin);
#endif // LOCAL
int N,M,Q,x,y,cott,n;
scanf("%d%d",&N,&M);
memset(ans,0,sizeof(ans));
for(int i=1;i<=N;i++){
scanf("%d",&n); //原来的n[maxn]也可以省掉了
ans[i][n]++;
for(int j=1;j<=M;j++) ans[i][j]+=ans[i-1][j]; //边输入边维护 前面的所有信息都要维护过来1-M的出现次数
//前面用了j<i,i可能很大,不越界才怪,改的时候,不要漏地方没改
}
scanf("%d",&Q);
while(Q--){
cott=0;
scanf("%d%d",&x,&y);
for(int i=1;i<=M;i++){ if((ans[y][i]-ans[x-1][i])>0) cott++; //注意索引
}
printf("%d",cott);
if(Q) printf("n");
}
return 0;
}
前面数组越界了,返回了一个RF,在不知道是越界引起的时候,我加了个#include 以后返回了WA,嘿嘿挺好玩的。
用前缀和相对n^2预处理memory小了很多,但显然n^2预处理要快一点,
特别是Q比较大,很接近上限的时候,Q->1e6,且n->2000,m->100,O(n*m+Q*m)>>O(n^2+Q)。
- THE END -
最后修改:2024年11月16日
非特殊说明,本博所有文章均为博主原创,未经许可不得转载。
如经许可后转载,请注明出处:https://prolightsfxjh.com/article/uestc-1256/
共有 0 条评论