码迷,mamicode.com
首页 > 其他好文 > 详细

随机的点

时间:2017-09-03 18:49:11      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:rip   time   splay   blog   答案   img   手动   max   desc   


描述 Description
陶陶为了给一道平面几何题出数据,需要产生 N 个点(x[i],y[i])。已知x,y是由伪随机函数顺序产生,即:
X[i+1] = (X[i]*Ax+Bx+i) mod Cx (X[1], Ax,Bx,Cx 是事先给定的)
Y[i+1] = (Y[i]*Ay+By+i) mod Cy (Y[1], Ay,By,Cy 是事先给定的)

这样,就可以快速连续产生很多点坐标(X[i], Y[i])。
不幸的是,这样产生的点有可能有相同的,虽然这种几率很少,但严谨的陶陶不允许这种事发生。陶陶要求你帮助他解决最少要产生前多少项时,正好有 N 个不相同的点。



输入格式 Input Format
第一行。一个整数 N .
第二行:4个整数 X[1]、 Ax、Bx、Cx .
第三行:4个整数 Y[1]、 Ay、By、Cy .


输出格式 Output Format
一个整数 M 。表示最少要连续产生 M 个点,正好有 N 个不相同的点。数据保证有答案。


样例输入 Sample Input
21
2 4 3 6
5 2 3 13


样例输出 Sample Output
24


时间限制 Time Limitation
1s


注释 Hint
1<=N<=1,000,000, 其它所有数据都在[0...1,000,000,000]范围内。


来源 Source
经典问题

 

      思路:对于刚学hash的焫鷄,书上给的模板是求一个数x的查找。但这道题是求一个坐标,有两个数怎么办呢??仔细一想回发现因为你用hash存的就是一个位置,所以你可以直接让(x+y)在取模那个大的质数,然后其他操作就和普通的hash一样了。然后你高高兴兴的把程序交上去。。。(超时???)听century一说,你必须的让x和y乘一个大数相加在取模,这是为什么呢??因为在你没有乘一个大数的时候刚开始的x,y相加取模的值也不会改变,所以你前面存的点就过于密集,导致查找时时间过慢,如果你乘上一个大数,就会使这个hash变得散,所以时间复杂度就大大降低了。然后你又兴冲冲的交了上去。。。。。(wrong answer???),你会发现x1,y1为零的点你的答案都加了一??这又是为什么呢??因为你刚开始给这个结构体付的值为0,所以刚开始他就判断x1,y1为零的点已经存在了,所以你只需手动付一下x的值为-1就好了

    

技术分享
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int maxprime=2323237;
const int step=7;
struct shadow
{
    long long x,y,num;
}hash[maxprime+5];
int q,w;
int find(long long g,long long k)
{
    int temp=(g*499979+k*299993)%maxprime;
    while((hash[temp].num)&&(hash[temp].x!=g||hash[temp].y!=k))
    {
        temp+=step;
        if(temp>=maxprime)
            temp-=maxprime;
    } 
    return temp;
}
int ans=0,h=0;
void insert(long long g,long long k)
{
    int now=find(g,k);
    if(hash[now].y==k&&hash[now].x==g)
        return;
    else
    {
        h++;
        hash[now].x=g;
        hash[now].y=k;
        hash[now].num=1;
    }
}
int main()
{
    //freopen("add.out","w",stdout);
    memset(hash,0,sizeof(hash));
    for(int i=0;i<=2323237+4;i++)
        hash[i].x=-1;
    int n;
    cin>>n;
    int x1,a1,b1,c1;
    cin>>x1>>a1>>b1>>c1;
    int y1,a2,b2,c2;
    cin>>y1>>a2>>b2>>c2;
    long long g=x1,k=y1;
    for(int i=1;;i++)
    {
        insert(g,k);
        g=(g*a1+b1+i)%c1;
        k=(k*a2+b2+i)%c2;
        //cout<<g<<‘ ‘<<k<<endl;
        ans++;
        if(h==n)
        {
            cout<<ans<<endl;
            break;
        }
    }
    return 0;
}
<( ̄ ﹌  ̄)>

 

随机的点

标签:rip   time   splay   blog   答案   img   手动   max   desc   

原文地址:http://www.cnblogs.com/lcyhaha/p/7470225.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!