NOIP2013Day1解题报告
本来今天晚上拿13年NOIP的题目来做一下,测测能够得多少分,结果一晚上把Day1写完竟然AK了,吼吼吼
D1T1,题目:http://codevs.cn/problem/3285/
很水的一道快速幂啊,题目竟然还刚好有0号节点来降低难度,记住对于转圈之后的位置要往取模方面想
ans=(x+m*10k)%n,原本是x号位置,每次往前走m个位置,共走了10k,最后再对于圈的大小取模即为最终位置
模意义下可变形,ans=x+m*10k%n=x+m*(10k%n)%n
其中10k%n不就是个快速幂取模吗?直接上模板:http://www.cnblogs.com/hadilo/p/5719139.html
简单AC
1 // Copyright(c) Hadilo.All Rights Reserved. 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cmath> 6 #include<iostream> 7 #include<algorithm> 8 #include<queue> 9 #include<stack> 10 #include<ctime> 11 #define fre(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout); 12 using namespace std; 13 typedef long long LL; 14 typedef double db; 15 const long double CPS=CLOCKS_PER_SEC,TL=0.998; 16 const int oo=2147483647; 17 inline int read() 18 { 19 int re=0; 20 bool fu=0; 21 char ch=getchar(); 22 while ((ch>'9'||ch<'0')&&ch!='-') ch=getchar(); 23 if (ch=='-') 24 { 25 fu=1; 26 ch=getchar(); 27 } 28 while (ch>='0'&&ch<='9') 29 { 30 re=re*10+ch-'0'; 31 ch=getchar(); 32 } 33 return fu?-re:re; 34 } 35 int n; 36 inline int mi(LL a,int b) 37 { 38 LL k=1; 39 a%=n; 40 while (b) 41 { 42 if (b&1) k=k*a%n; 43 b>>=1; 44 a=a*a%n; 45 } 46 return (int)k; 47 } 48 int main() 49 { 50 fre("circle"); 51 n=read(); 52 cout<<(read()*mi(10,read())+read())%n<<endl; 53 return 0; 54 }
D1T2,题目:http://codevs.cn/problem/3286/
其实看完题目我是先写的T3再写的T2,因为感觉这个不是太好证明
可伪证一下,把两个数组排序后对应位置即为最终答案,因为找不出反例而且感觉很正确
则对于两个数组a、b分别离散化一下,再记一个数组c[i]为b[i]离散化的值在a[i]中的位置
最后对 c 数组求逆序对即可,归并排序或树状数组都可以,我写的是归并排序
1 // Copyright(c) Hadilo.All Rights Reserved. 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cmath> 6 #include<iostream> 7 #include<algorithm> 8 #include<queue> 9 #include<stack> 10 #include<ctime> 11 #define fre(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout); 12 using namespace std; 13 typedef long long LL; 14 typedef double db; 15 const long double CPS=CLOCKS_PER_SEC,TL=0.998; 16 const int oo=2147483647,N=100001,mo=99999997; 17 inline int read() 18 { 19 int re=0; 20 bool fu=0; 21 char ch=getchar(); 22 while ((ch>'9'||ch<'0')&&ch!='-') ch=getchar(); 23 if (ch=='-') 24 { 25 fu=1; 26 ch=getchar(); 27 } 28 while (ch>='0'&&ch<='9') 29 { 30 re=re*10+ch-'0'; 31 ch=getchar(); 32 } 33 return fu?-re:re; 34 } 35 struct gap 36 { 37 int x,num; 38 }; 39 gap a[N]; 40 int b[N],c[N],p[N],ans; 41 inline void gb(int l,int r) 42 { 43 if (l==r) return; 44 int mid=(l+r)>>1,i,j,top=0; 45 gb(l,mid); 46 gb(mid+1,r); 47 for (i=l,j=mid+1;i<=mid&&j<=r;) 48 { 49 if (c[i]<=c[j]) b[++top]=c[i++]; 50 else 51 { 52 b[++top]=c[j++]; 53 if ((ans+=mid-i+1)>mo) ans-=mo; 54 } 55 } 56 while (i<=mid) b[++top]=c[i++]; 57 while (j<=r) b[++top]=c[j++]; 58 for (;top;top--,r--) c[r]=b[top]; 59 } 60 inline bool cmp(gap x,gap y) 61 { 62 return x.x<y.x; 63 } 64 int main() 65 { 66 fre("math"); 67 int i,n=read(); 68 for (i=1;i<=n;i++) a[i]=(struct gap){read(),i}; 69 sort(a+1,a+i,cmp); 70 for (i=1;i<=n;i++) 71 { 72 b[a[i].num]=i; 73 p[i]=a[i].num; 74 a[i]=(struct gap){read(),i}; 75 } 76 sort(a+1,a+i,cmp); 77 for (i=1;i<=n;i++) c[a[i].num]=p[i]; 78 gb(1,n); 79 printf("%d\n",ans); 80 return 0; 81 }
D1T3,题目:http://codevs.cn/problem/3287/
题目要求路径上的所有边权的最小值最大
对于两点之间的路径,不就是走最大的那几个边可以保证答案最大
而在一棵树中是能保证图刚好连通的,做一颗最大生成树
然后对于每组询问直接倍增求LCA即可,记得统计路径上的边权最小值
1 // Copyright(c) Hadilo.All Rights Reserved. 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cmath> 6 #include<iostream> 7 #include<algorithm> 8 #include<queue> 9 #include<stack> 10 #include<ctime> 11 #define fre(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout); 12 using namespace std; 13 typedef long long LL; 14 typedef double db; 15 const long double CPS=CLOCKS_PER_SEC,TL=0.998; 16 const int oo=2147483647,N=10001,M=50001,L=15,N2=20001; 17 inline int read() 18 { 19 int re=0; 20 bool fu=0; 21 char ch=getchar(); 22 while ((ch>'9'||ch<'0')&&ch!='-') ch=getchar(); 23 if (ch=='-') 24 { 25 fu=1; 26 ch=getchar(); 27 } 28 while (ch>='0'&&ch<='9') 29 { 30 re=re*10+ch-'0'; 31 ch=getchar(); 32 } 33 return fu?-re:re; 34 } 35 struct gap 36 { 37 int u,v,w; 38 }; 39 gap e[M]; 40 int first[N],f[N][L],g[N][L],next[N2],v[N2],w[N2],d[N],fa[N],t; 41 inline int log2(int x) 42 { 43 int k=-1; 44 while (x) 45 { 46 k++; 47 x>>=1; 48 } 49 return k; 50 } 51 inline int find(int x) 52 { 53 return fa[x]==x?x:fa[x]=find(fa[x]); 54 } 55 inline void dfs(int x,int last) 56 { 57 if (last) fa[x]=find(last); 58 t=max(t,d[x]=d[last]+1); 59 f[x][0]=last; 60 for (int i=first[x];i;i=next[i]) 61 if (v[i]!=last) 62 { 63 g[v[i]][0]=w[i]; 64 dfs(v[i],x); 65 } 66 } 67 inline bool cmp(gap x,gap y) 68 { 69 return x.w>y.w; 70 } 71 int main() 72 { 73 fre("truck"); 74 int n=read(),m=read(),i,j,x,y,top=0,ans; 75 for (i=1;i<=m;i++) e[i]=(struct gap){read(),read(),read()}; 76 sort(e+1,e+1+m,cmp); 77 for (i=1;i<=n;i++) fa[i]=i; 78 for (i=1;i<=m;i++) 79 { 80 x=find(e[i].u); 81 y=find(e[i].v); 82 if (x!=y) 83 { 84 fa[x]=y; 85 top++; 86 next[top]=first[v[top+n]=e[i].u]; 87 first[e[i].u]=top; 88 next[top+n]=first[v[top]=e[i].v]; 89 first[e[i].v]=top+n; 90 w[top]=w[top+n]=e[i].w; 91 } 92 } 93 for (i=1;i<=n;i++) fa[i]=i; 94 for (i=1;i<=n;i++) if (fa[i]==i) dfs(i,0); 95 t=log2(t); 96 for (i=1;i<=t;i++) 97 for (j=1;j<=n;j++) 98 { 99 f[j][i]=f[f[j][i-1]][i-1]; 100 g[j][i]=min(g[j][i-1],g[f[j][i-1]][i-1]); 101 } 102 m=read(); 103 while (m--) 104 { 105 x=read(); 106 y=read(); 107 if (find(x)==find(y)) 108 { 109 ans=oo; 110 if (d[x]<d[y]) swap(x,y); 111 for (i=log2(d[x]-d[y]);i>=0;i--) 112 if (f[x][i]&&d[f[x][i]]>=d[y]) 113 { 114 ans=min(ans,g[x][i]); 115 x=f[x][i]; 116 } 117 if (x==y) 118 { 119 printf("%d\n",ans); 120 continue; 121 } 122 for (i=log2(d[x]);i>=0;i--) 123 if (f[x][i]&&f[x][i]!=f[y][i]) 124 { 125 ans=min(ans,min(g[x][i],g[y][i])); 126 x=f[x][i]; 127 y=f[y][i]; 128 } 129 printf("%d\n",min(ans,min(g[x][0],g[y][0]))); 130 } 131 else printf("-1\n"); 132 } 133 return 0; 134 }
版权所有,转载请联系作者,违者必究