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 }