noip2013 提高组
Posted 友人A
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了noip2013 提高组相关的知识,希望对你有一定的参考价值。
T1 转圈游戏 题目传送门
果不其然 第一题还是模拟题 一波快速幂解决问题
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int read(){ int ans=0,f=1,c=getchar(); while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();} while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();} return ans*f; } int n,m,k,x; int qmod(int a,int b,int c){ int ans=1; while(b){ if(b&1) ans=ans*a%c; b=b/2; a=a*a%c; } return ans; } int main() { n=read(); m=read(); k=read(); x=read(); int v=qmod(10,k,n); printf("%d\n",(v*m+x)%n); return 0; }
T2 火柴排队 题目传送门
这是道树状数组求逆序数对的题目 当然还要加一波离散化就好了 不过这题的离散化很玄学哇 2333
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=100007,mod=99999997; int read(){ int ans=0,f=1,c=getchar(); while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();} while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();} return ans*f; } struct node{int w,pos;}a[M],b[M]; bool cmp(node a,node b){return a.w<b.w;} int c[M],sum[M],n; LL ans; int lowbit(int x){return x&-x;} void insert(int x){ while(x<=n){ sum[x]++; x+=lowbit(x); } } int push_sum(int x){ int ans=0; while(x){ans+=sum[x]; x-=lowbit(x);} return ans; } int main() { n=read(); for(int i=1;i<=n;i++) a[i].w=read(),a[i].pos=i; for(int i=1;i<=n;i++) b[i].w=read(),b[i].pos=i; sort(a+1,a+1+n,cmp); sort(b+1,b+1+n,cmp); for(int i=1;i<=n;i++) c[a[i].pos]=b[i].pos; for(int i=1;i<=n;i++){ insert(c[i]); ans=(ans+i-push_sum(c[i]))%mod; } printf("%lld\n",ans); return 0; }
T3 货车运输 题目传送门
几乎是裸的lca吧 用lca维护一波最近公共祖先和路径最小值就好了
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=150007; int read(){ int ans=0,f=1,c=getchar(); while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();} while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();} return ans*f; } int w[M],n,f[M][2]; int main() { n=read(); for(int i=1;i<=n;i++) w[i]=read(),f[i][0]=f[i][1]=1; for(int i=1;i<=n;i++) for(int j=i-1;j;j--){ if(w[i]>w[j]) f[i][1]=max(f[i][1],f[j][0]+1); if(w[j]>w[i]) f[i][0]=max(f[i][0],f[j][1]+1); if(f[i][0]!=1&&f[i][1]!=1) break; } printf("%d\n",max(f[n][0],f[n][1])); return 0; }
T4 积木大赛 题目传送门
这道题就是我们只考虑相邻两列h1 h2 容易证明他的无后效性
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=150007; int read(){ int ans=0,f=1,c=getchar(); while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();} while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();} return ans*f; } int w[M],n,f[M][2]; int main() { n=read(); for(int i=1;i<=n;i++) w[i]=read(),f[i][0]=f[i][1]=1; for(int i=1;i<=n;i++) for(int j=i-1;j;j--){ if(w[i]>w[j]) f[i][1]=max(f[i][1],f[j][0]+1); if(w[j]>w[i]) f[i][0]=max(f[i][0],f[j][1]+1); if(f[i][0]!=1&&f[i][1]!=1) break; } printf("%d\n",max(f[n][0],f[n][1])); return 0; }
T5 花匠 题目传送门
正解似乎是算拐点+1 数据随机dp水过
0表示他是作为比较小的那个点 1则相反
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=150007; int read(){ int ans=0,f=1,c=getchar(); while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();} while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();} return ans*f; } int w[M],n,f[M][2]; int main() { n=read(); for(int i=1;i<=n;i++) w[i]=read(),f[i][0]=f[i][1]=1; for(int i=1;i<=n;i++) for(int j=i-1;j;j--){ if(w[i]>w[j]) f[i][1]=max(f[i][1],f[j][0]+1); if(w[j]>w[i]) f[i][0]=max(f[i][0],f[j][1]+1); if(f[i][0]!=1&&f[i][1]!=1) break; } printf("%d\n",max(f[n][0],f[n][1])); return 0; }
T6 华容道 题目传送门
这道题黄学长都弃坑了 我纠结什么呢 以后补吧 hzwer
以上是关于noip2013 提高组的主要内容,如果未能解决你的问题,请参考以下文章