2016.10.30 NOIP模拟赛 day2 PM 整理

满分:300分  

直接全部爆零,真的是很坑啊!

10.30的题目+数据:链接:http://pan.baidu.com/s/1jHXLace 密码:i784

T1:

题目中的难点就是每次折叠的点可能应经被覆盖了,我的做法是递归去推出它现在在哪个位置,不仅超时,而且答案错误。

也曾想过用数组去存下它当前的位置,但是被10^18的数据吓到了。

正解:并不是所有的坐标都有用,仅仅是那m个将要用到的点有用,所以每次折叠,就只对之后的有用的k个点进行更新,这样就行了。

 时间复杂度O(m^2) 不会超时的。

 1 #include<iostream>
 2 using namespace std;
 3 #include<cstdio>
 4 #define M 3004
 5 typedef long long ll;
 6 ll pos[M];
 7 ll n,m;
 8 int main()
 9 {
10     freopen("he.in","r",stdin);
11     freopen("he.out","w",stdout);
12     cin>>n>>m; 
13     for(int i=1;i<=m;++i)
14       cin>>pos[i];
15     ll l=0,r=n;
16     for(int i=1;i<=m;++i)
17     {
18         ll x=pos[i];
19         if(2*x>=(l+r))
20         {
21             r=x;
22             for(int j=i+1;j<=m;++j)
23               if(pos[j]>x) pos[j]=x+x-pos[j];
24         }
25         else
26         {
27             l=x;
28             for(int j=i+1;j<=m;++j)
29               if(pos[j]<x) pos[j]=x+x-pos[j];
30         }
31     }
32     cout<<r-l;
33     fclose(stdin);
34     fclose(stdout);
35     return 0;
36 }

T2:相信大牛们一眼就看出了这道题目用BSGS算法。注明:该算法我不会。

只会50分。

 

 1 /*
 2 扩展欧几里得模板打错了。
 3  
 4 */
 5 #include<iostream>
 6 #include<cstdio>
 7 using namespace std;
 8 typedef long long ll;
 9 void exgcd(ll a,ll b,ll &x,ll &y,ll &gc)
10 {
11     if(!b)
12     {
13         x=1;y=0;
14         gc=a;
15         return;
16     }
17     exgcd(b,a%b,y,x,gc);
18     y-=(a/b)*x;
19 }
20 ll read()
21 {
22     ll ret=0,ff=1;
23     char s1=getchar();
24     while(s1<'0'||s1>'9')
25     {
26         if(s1=='-') ff=-1;
27         s1=getchar();
28     }
29     while(s1>='0'&&s1<='9')
30     {
31         ret=ret*10+s1-'0';
32         s1=getchar();
33     }
34     return ret*ff;
35     
36 }
37 int main()
38 {
39     freopen("she.in","r",stdin);
40     freopen("she.out","w",stdout);
41     ll l,r,s,m;
42     int T;
43     scanf("%d",&T);
44     while(T--)
45     {
46         //cin>>m>>s>>l>>r;
47         m=read();s=read();l=read();
48         r=read();
49         if(l>=m)
50         {
51             printf("-1\n");
52             continue;
53         }
54         if(l==r)
55         {
56             ll x,y,gc;
57             exgcd(s,m,x,y,gc);
58             if(l%gc)
59             {
60                 cout<<-1<<endl;
61             }
62             else
63             {
64                 x=x*l/gc;
65                 ll m1=m/gc;
66                 x=(x%m1+m1)%m1;
67                 if(x==0) x+=m1;
68                 cout<<x<<endl;
69              }
70             continue; 
71         }
72         bool flag=false;
73         for(int x=1;x<=1000000;++x)
74         {
75             ll res=(s%m*x%m)%m;
76             if(res>=l&&res<=r) 
77             {
78                 printf("%d\n",x);
79                 flag=true;
80                 break;
81             }
82         }
83         if(flag) continue;
84         printf("-1\n");
85     }
86     fclose(stdin);
87     fclose(stdout);
88     return 0;
89 }

 

标程:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 
 7 using namespace std;
 8 
 9 const int maxn=100010;
10 
11 int L,R,s,m;
12 
13 struct rec
14 {
15     int v,p;
16     bool operator<(const rec &a)const
17     {
18         return v<a.v;
19     }
20 }z[maxn];
21 
22 void solve(int l,int r,int &res,int delta,int p)
23 {
24     if (l>r) return;
25     int left=l-1,right=r;
26     while (left+1!=right)
27     {
28         int mid=(left+right)>>1;
29         if ((z[mid].v+delta)%m>=L) right=mid;
30         else left=mid;
31     }
32     int v=z[right].v+delta;
33     v%=m;
34     if (v>=L && v<=R)
35     {
36         for (int a=l;a<=r;a++)
37             if ((z[a].v+delta)%m>=L && (z[a].v+delta)%m<=R)
38             {
39                 if (res) res=min(res,z[a].p+p-1);
40                 else res=z[a].p+p-1;
41             }
42     }
43 }
44 
45 int main()
46 {
47     freopen("she.in","r",stdin);
48     freopen("she.out","w",stdout);
49 
50     int test;
51     scanf("%d",&test);
52     for (int p=1;p<=test;p++)
53     {
54         scanf("%d%d%d%d",&m,&s,&L,&R);
55         if (R>=m) R=m-1;
56         s%=m;
57         int size=(int)sqrt(m);
58         int res=0;
59         for (int a=1;a<=size && !res;a++)
60         {
61             z[a].v=(z[a-1].v+s)%m;
62             if (z[a].v>=L && z[a].v<=R) res=a;
63             z[a].p=a;
64         }
65         sort(z+1,z+size+1);
66         for (int a=size+1;a<=m && !res;a+=size)
67         {
68             int delta=(long long)size*s%m*((a-1)/size)%m;
69             int l=0,r=size;
70             while (l+1!=r)
71             {
72                 int mid=(l+r)>>1;
73                 if (z[mid].v+delta>=m) r=mid;
74                 else l=mid;
75             }
76             if (z[r].v+delta<m) r++;
77             solve(1,r-1,res,delta,a);
78             solve(r,size,res,delta,a);
79         }
80         if (res) printf("%d\n",res);
81         else printf("-1\n");
82     }
83 
84     return 0;
85 }

T3:听说很难,我不会,只有标程

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 
 7 using namespace std;
 8 
 9 const int maxn=1010;
10 
11 int n,k,pre[maxn],next[maxn];
12 
13 long double p[maxn],q[maxn];
14 
15 void del(int b)
16 {
17     int a=pre[b],c=next[b];
18     long double pa=p[a],pb=p[b],pc=p[c];
19     p[a]=pa*pb/(1-pa*(1-pb));q[a]=1-p[a];
20     q[c]=(1-pc)*(1-pb)/(1-pb*(1-pc));p[c]=1-q[c];
21     next[a]=c;pre[c]=a;
22 }
23 
24 long double solve()
25 {
26     if (n<=2) return 1;
27     if (n<=3) return k==1 ? p[1] : q[2];
28     for (int a=1;a<=n;a++)
29         pre[a]=a-1,next[a]=a+1;
30     pre[1]=n;next[n]=1;
31     if (k==1)
32     {
33         for (int a=2;a<n-1;a++)
34             del(a);
35         return p[1];
36     }
37     if (k==n-1)
38     {
39         for (int a=2;a<n-1;a++)
40             del(a);
41         return q[n-1];
42     }
43     for (int a=2;a<k;a++)
44         del(a);
45     for (int a=k+1;a<n-1;a++)
46         del(a);
47     del(k);
48     return q[k]*p[1]+p[k]*q[n-1];
49 }
50 
51 int main()
52 {
53     freopen("it.in","r",stdin);
54     freopen("it.out","w",stdout);
55 
56     int test;
57     scanf("%d",&test);
58     for (int px=1;px<=test;px++)
59     {
60         scanf("%d%d",&n,&k);
61         for (int a=1;a<=n;a++)
62         {
63             double v;
64             scanf("%lf",&v);
65             p[a]=v;
66             q[a]=1-p[a];
67         }
68         printf("%.9lf\n",(double)solve());
69     }
70 
71     return 0;
72 }

 

转载于:https://www.cnblogs.com/c1299401227/p/6055460.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值