2017-10-12 NOIP模拟赛
斐波那契
/* 相同颜色的节点与父亲节点的差相等,且是一个小于它的最大斐波那契数 所以降两个点同时减去小与它的最大斐波那契数,直到两点相等 */ #include<cstdio> const int maxm=3e5+30; int m; long long f[59]={1,1}; int main(){ freopen("fibonacci.in","r",stdin);freopen("fibonacci.out","w",stdout); for(int i=2;i<=58;i++) f[i]=f[i-1]+f[i-2]; scanf("%d",&m); long long a,b; while(m--){ scanf("%lld%lld",&a,&b); for(int i=58;a!=b;i--){ if(a>f[i]) a-=f[i]; if(b>f[i]) b-=f[i]; } printf("%lld\n",a); } return 0; }
数颜色
#include<iostream> #include<cstdio> #define maxn 300010 using namespace std; int n,m,a[maxn],sum[maxn],pos[maxn],s[1001][1001],mx; bool flag1,flag2; void work2(){ int op,l,r,x; while(m--){ scanf("%d",&op); if(op==1){ scanf("%d%d%d",&l,&r,&x); if(pos[x]>r||pos[x]<l)putchar('0'); else putchar('1'); putchar('\n'); } else { scanf("%d",&x); swap(a[x],a[x+1]); swap(pos[a[x]],pos[a[x+1]]); } } } void work(){ for(int i=1;i<=n;i++){ for(int j=1;j<=mx;j++){ if(j==a[i])s[i][j]=s[i-1][j]+1; else s[i][j]=s[i-1][j]; } } int op,l,r,x; for(int i=1;i<=m;i++){ scanf("%d",&op); if(op==1){ scanf("%d%d%d",&l,&r,&x); int cnt=s[r][x]-s[l-1][x]; printf("%d\n",cnt); } else { scanf("%d",&x); s[x][a[x]]--; s[x][a[x+1]]++; } } } int main(){ //freopen("Cola.txt","r",stdin); freopen("color.in","r",stdin);freopen("color.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); mx=max(mx,a[i]); sum[a[i]]++; if(sum[a[i]]>1)flag2=1; pos[a[i]]=i; } if(!flag2){//所有兔子亚瑟都不相同 work2(); return 0; } if(n<=1000){work();return 0;} int op,l,r,x; for(int i=1;i<=m;i++){ scanf("%d",&op); if(op==1){ scanf("%d%d%d",&l,&r,&x); int w=r-l+1; if(w<=n-w){ int cnt=0; for(int j=l;j<=r;j++)if(a[j]==x)cnt++; printf("%d\n",cnt); continue; } else { int cnt=0; for(int j=1;j<=l;j++)if(a[j]==x)cnt++; for(int j=r+1;j<=n;j++)if(a[j]==x)cnt++; cnt=sum[x]-cnt; printf("%d\n",cnt); } } else { scanf("%d",&x); swap(a[x],a[x+1]); } } return 0; }
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorithm> #define maxn 300010 using namespace std; vector<int>a[maxn]; int n,m,l,r,x; int pos[maxn]; int main(){ freopen("color.in","r",stdin);freopen("color.out","w",stdout); //freopen("Cola.txt","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&pos[i]),a[pos[i]].push_back(i); for(int i=1;i<=300000;i++)sort(a[i].begin(),a[i].end()); for(int i=1;i<=m;i++){ int opt;scanf("%d",&opt); if(opt==1){ scanf("%d%d%d",&l,&r,&x); int ll=0,rr=a[x].size()-1,ans=-1,mid; while(ll<=rr){ mid=(ll+rr)>>1; if(a[x][mid]>=l)ans=mid,rr=mid-1; else ll=mid+1; } if(ans==-1){printf("0\n");continue;} ll=0,rr=a[x].size()-1;int ans2=-1; while(ll<=rr){ int mid=(ll+rr)>>1; if(a[x][mid]<=r)ans2=mid,ll=mid+1; else rr=mid-1; } if(ans2==-1){printf("0\n");continue;} else printf("%d\n",ans2-ans+1); } else { scanf("%d",&x); if(pos[x]==pos[x+1])continue; else { a[pos[x]][lower_bound(a[pos[x]].begin(),a[pos[x]].end(),x)-a[pos[x]].begin()]++; a[pos[x+1]][lower_bound(a[pos[x+1]].begin(),a[pos[x+1]].end(),x+1)-a[pos[x+1]].begin()]--; swap(pos[x],pos[x+1]); } } } return 0; }
分组
#include<iostream> #include<cstdio> #include<cmath> #define maxn 131073 using namespace std; int n,k,a[maxn],q[maxn],ans=-1,cnt,pp[maxn],numm,mid; bool flag; bool no(int w){ int ww=sqrt(w); if(w==ww*ww)return 1; return 0; } void dfs(int zu,int pos){ if(flag)return; if(pos==n+1&&zu<=mid){ flag=1; return; } int num=numm; int p[100]; for(int i=1;i<=numm;i++)p[i]=pp[i]; if(zu<mid&&pos!=1){ numm=0; pp[++numm]=pos; q[zu]=pos-1; dfs(zu+1,pos+1); if(flag)return; } bool ok=1; for(int i=1;i<=num;i++) if(no(a[pos]+a[p[i]])){ ok=0; break; } if(ok==1){ numm=num;for(int i=1;i<=numm;i++)pp[i]=p[i]; numm=numm+1; pp[numm]=pos; dfs(zu,pos+1); if(flag)return; } if(flag)return; } bool check(){ flag=0;numm=0; dfs(1,1); if(flag)return 1; return 0; } int main(){ //freopen("Cola.txt","r",stdin); freopen("division.in","r",stdin);freopen("division.out","w",stdout); scanf("%d%d",&n,&k); for(int i=1;i<=n;i++)scanf("%d",&a[i]); if(k==1){ int l=1,r=n; while(l<=r){ mid=(l+r)>>1; if(check())ans=mid,r=mid-1; else l=mid+1; } if(ans!=-1){ printf("%d\n",ans); for(int i=1;i<ans;i++)printf("%d\n",q[i]); return 0; } return 0; } printf("1\n\n"); return 0; }
#include<iostream> #include<cstdio> #include<cstring> #define maxn 131073 using namespace std; int n,m,k; int a[maxn],b[maxn],f[maxn<<1]; bool vis[maxn],dvis[maxn],issqr[maxn<<1]; int find(int x){ return f[x]>0?(f[x]=find(f[x])):x; } void merge(int u,int v){ u=find(u),v=find(v); if(u!=v){ if(f[u]>f[v])swap(u,v); f[u]+=f[v];f[v]=u; } } bool check(int u,int v){ int r1=find(u),r2=find(u+maxn); int s1=find(v),s2=find(v+maxn); if(r1==s1||r2==s2)return 1; merge(r1,s2);merge(r2,s1); return 0; } void work1(){ for(int i=n,j=n;i;){ for(bool flag=1;j;j--){ for(int k=1;k*k-a[j]<maxn;k++){ if(k*k-a[j]<=0)continue; if(vis[k*k-a[j]]){flag=0;break;} } if(!flag)break; vis[a[j]]=1; } if(!j)break;b[++m]=j; for(;i>j;i--)vis[a[i]]=0; } } void work2(){ memset(f,-1,sizeof(f)); for(int i=1;i*i<2*maxn;i++)issqr[i*i]=1; for(int i=n,j=n;i;){ for(bool flag=1;j;j--){ if(vis[a[j]]){ if(issqr[a[j]+a[j]]){ if(dvis[a[j]])break; for(int k=1;k*k-a[j]<maxn;k++){ if(k*k-a[j]<=0)continue; if(vis[k*k-a[j]]&&k*k!=a[j]*2){flag=0;break;} } if(!flag)break;dvis[a[j]]=1; } } else { for(int k=1;k*k-a[j]<maxn;k++){ if(k*k-a[j]<=0)continue; if(vis[k*k-a[j]]){ if(check(k*k-a[j],a[j])){flag=0;break;} } } if(!flag)break;vis[a[j]]=1; } } if(!j)break;b[++m]=j; for(;i>j;i--)f[a[i]]=f[a[i]+maxn]=-1,vis[a[i]]=0,dvis[a[i]]=0; } } int main(){ //freopen("Cola.txt","r",stdin); freopen("division.in","r",stdin);freopen("division.out","w",stdout); scanf("%d%d",&n,&k); for(int i=1;i<=n;i++)scanf("%d",&a[i]); if(k==1)work1(); else work2(); printf("%d\n",m+1); for(int i=m;i;i--)printf("%d ",b[i]); putchar('\n'); return 0; }
/* T1考场上没想出正解来,就打了个暴力,暴力挂了,得到正解发现这题是这么的简单 T2,T3直接练暴力了,T3调了将近一个半小时 这次考试成绩不理想,主要是败在T1了,noip的T1应该是一眼题,这个T1不是 再加上心态不好 考场上总还是不免有一些题想不出正解,但是暴力出错就太可惜了,以后暴力还是要努力写的,尽量不要出错误(不要不屑于手造数据),希望以后能避免类似今天T1的错误 Noip前每次模拟考试出现的失误都有可能反映在正式考试中 切记切记,下不为例 */