# 【NOIP2013】提高组

Day1

T1转圈游戏

 1 #include<cstdio>
2 #include<algorithm>
3 int ksm(long long x,int y,int p){
4     int res=1;
5     while(y){
6         if(y&1)res=res*x%p;
7         x=x*x%p;
8         y>>=1;
9     }
10     return res;
11 }
12 int main(){
13     int n,m,k,x;
14     scanf("%d %d %d %d",&n,&m,&k,&x);
15     printf("%d",(x+m*ksm(10,k,n)%n)%n);
16     return 0;
17 }
D1 T1

T2火柴排队

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 #define lowbit(x) x&-x
5 const int N=1e5+7,mod=99999997;
6 struct node{
7     int wi,id;
8 }e[N],q[N];
9 int n,pai[N],rank[N],to[N],tr[N];
11     int ans=0,f=1;char c=getchar();
12     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
13     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
14     return ans*f;
15 }
16 int ans=0;
17 bool cmp(node aa,node bb){return aa.wi<bb.wi;}
18 int sum(int x){
19     long long ss=0;
20     for(;x<=n;x+=lowbit(x))ss=(ss+tr[x])%mod;
21     return ss;
22 }
24     for(;x;x-=lowbit(x))tr[x]++;
25 }
26 void ni(){
27     for(int i=1;i<=n;i++){
28         int ss=sum(rank[i]);
29         ans=(ans+ss)%mod;
31     }
32 }
33 int main(){
36     std::sort(e+1,e+1+n,cmp);
37     for(int i=1;i<=n;i++)pai[e[i].id]=i;
38     for(int i=1;i<=n;i++)to[pai[i]]=i;
40     std::sort(q+1,q+1+n,cmp);
41     for(int i=1;i<=n;i++)rank[q[i].id]=to[i];
42     ni();
43     printf("%d",ans);
44     return 0;
45 }
D1 T2

T3货车运输

 1 #include<cstdio>
2 #include<cstring>
3 #include<queue>
4 #include<algorithm>
5 const int M=5e4+10,N=1e4+7,inf=0x3f3f3f3f;
6 struct node{
7     int fr,to,w;
8     bool operator <(const node&p)const {return p.w>w;}
9 };
10 struct no{int ne,to,w;}e[N*2];
11 std::priority_queue<node>q;
12 int n,m,fa[N],tot=0,first[N],deep[N];
13 int mni[N][20],gr[N][20];
14 int min(int x,int y){return x>y?y:x;}
16     int ans=0,f=1;char c=getchar();
17     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
18     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
19     return ans*f;
20 }
21 void ins(int u,int v,int w){
22     e[++tot]=(no){first[u],v,w};first[u]=tot;
23 }
24 int getf(int x){return x==fa[x]?x:fa[x]=getf(fa[x]);}
25 void dfs(int x,int ff){
26     for(int i=1;(1<<i)<=deep[x];i++){
27         gr[x][i]=gr[gr[x][i-1]][i-1];
28         mni[x][i]=min(mni[x][i-1],mni[gr[x][i-1]][i-1]);
29     }
30     for(int i=first[x];i;i=e[i].ne){
31         int to=e[i].to;
32         if(to!=ff){
33             deep[to]=deep[x]+1;
34             gr[to][0]=x;mni[to][0]=e[i].w;
35             dfs(to,x);
36         }
37     }
38 }
39 int lca(int x,int y){
40     int mn=inf;
41     if(deep[x]<deep[y])std::swap(x,y);
42     int d=deep[x]-deep[y];
43     for(int i=0;(1<<i)<=deep[x]&&i<=20;i++)
44         if(d&(1<<i)){
45             mn=min(mn,mni[x][i]);
46             x=gr[x][i];
47         }
48     if(x==y)return mn;
49     for(int i=20;i>=0;i--){
50         if((1<<i)>deep[x]||gr[x][i]==gr[y][i])continue;
51         mn=min(mn,mni[x][i]);mn=min(mn,mni[y][i]);
52         x=gr[x][i];y=gr[y][i];
53     }
54     if(!gr[x][0])return -1;
55     mn=min(mn,min(mni[x][0],mni[y][0]));
56     return mn;
57 }
58 int main(){
60     for(int i=1,a,b,c;i<=m;i++){
62         q.push((node){a,b,c});
63     }
64     for(int i=1;i<=n;i++)fa[i]=i;
65     while(!q.empty()){
66         node p=q.top();q.pop();
67         int f1=getf(p.fr),f2=getf(p.to);
68         if(f1!=f2){
69             ins(p.fr,p.to,p.w);ins(p.to,p.fr,p.w);
70             fa[f1]=f2;
71         }
72     }
73     dfs(1,0);
75     while(qu--){
77         int mn=lca(x,y);
78         printf("%d\n",mn);
79     }
80     return 0;
81 }
D1 T3

Day2

T1积木大赛

 1 #include<cstdio>
2 #include<algorithm>
3 int main(){
4     int n,x,last=0,ans=0;
5     scanf("%d",&n);
6     for(int i=1;i<=n;i++){
7         scanf("%d",&x);
8         if(x>last)ans+=x-last;
9         last=x;
10     }
11     printf("%d",ans);
12     return 0;
13 }
D2 T1

T2花匠

 1 #include<cstdio>
2 #include<algorithm>
3 #include<cstring>
4 const int N=1e5+10;
5 int n,hi[N],tt;
7     int ans=0,f=1;char c=getchar();
8     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
9     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
10     return ans*f;
11 }
12 int main(){
15     if(n==1)return printf("1"),0;
16     int t=2;
17     while(t<=n&&hi[t]==hi[t-1])t++;
18     if(hi[t]>hi[t-1])tt=1;
19     else tt=0;
20     int sum=1;
21     for(int i=t+1;i<=n;i++){
22         if(hi[i]==hi[i-1])continue;
23         if(hi[i]>hi[i-1]&&!tt){
24             sum++;tt^=1;
25         }
26         else if(hi[i]<hi[i-1]&&tt){
27             sum++;tt^=1;
28         }
29     }
30     sum++;
31     printf("%d",sum);
32     return 0;
33 }
D2 T2

T3华容道

  1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 #include<queue>
5 #include<cmath>
6 #define mem(a,p) memset(a,p,sizeof(a))
7 const int N=35,inf=0x3f3f3f3f;
8 int n,m,q,h1,t1,h2,t2,ex,ey,sx,sy,tx,ty;
9 int mp[N][N],cc[6][2]={{0,0},{0,1},{1,0},{-1,0},{0,-1}};
10 int der[6]={0,4,3,2,1},step[N][N][6][6],dis[N][N][6];
11 //der[k]存k的反方向，防止走回去导致死循
12 //dis[x][y][i]表示起始点从i方向走到(x,y)这个点的最小代价
13 bool ok[N][N];
14 struct no{
15     int x,y,st,k;
16 }q1[4000005],q2[4000005];//q1、q2分别是用于bfs和SPFA的队列
17 int min(int x,int y){return x>y?y:x;}
19     int ans=0,f=1;char c=getchar();
20     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
21     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
22     return ans*f;
23 }
24 void pre(int x,int y){
25     for(int i=1;i<=4;i++){
26         if(!mp[x+cc[i][0]][y+cc[i][1]])continue;
27         for(int j=1;j<=4;j++){//mp[x][y]四个方向的格子（可移动的）两两相互到达所需代价
28             int ax=x+cc[i][0],ay=y+cc[i][1];
29             if(i==j||step[x][y][i][j])continue;
30             int px=x+cc[j][0],py=y+cc[j][1];
31             if(!mp[px][py])continue;
32             h1=1;t1=0;
33             mem(ok,0);
34             q1[++t1]=(no){ax,ay,0,i};
35             ok[ax][ay]=1;
36             int ans=-1;
37             while(h1<=t1){
38                 no p=q1[h1];h1++;
39                 if(p.x==px&&p.y==py){ans=p.st;break;}
40                 for(int k=1;k<=4;k++){
41                     int bx=p.x+cc[k][0],by=p.y+cc[k][1];
42                     if(k==der[p.k]||!mp[bx][by]||ok[bx][by]||(bx==x&&by==y))continue;//bfs
43                     q1[++t1]=(no){bx,by,p.st+1,k};
44                     ok[bx][by]=1;
45                 }
46             }
47             step[x][y][i][j]=step[x][y][j][i]=ans;
48         }
49     }
50 }
51 void pre_white(){//预处理白格子走到起始格子四周的代价
52     h2=1;t2=0;
53     for(int i=1;i<=4;i++){
54         if(!mp[sx+cc[i][0]][sy+cc[i][1]])continue;
55         mem(ok,0);h1=1;t1=0;
56         int px=sx+cc[i][0],py=sy+cc[i][1];
57         q1[++t1]=(no){ex,ey,0,0};ok[ex][ey]=1;
58         int ans=inf;
59         while(h1<=t1){
60             no p=q1[h1];h1++;
61             if(p.x==px&&p.y==py){
62                 ans=p.st;
63                 if(ans<inf){
64                     q2[++t2]=(no){px,py,ans+1,i};
65                     dis[px][py][i]=ans+1;
66                 }break;
67             }
68             for(int k=1;k<=4;k++){
69                 int bx=p.x+cc[k][0],by=p.y+cc[k][1];
70                 if(k==der[p.k]||!mp[bx][by]||ok[bx][by]||(bx==sx&&by==sy))continue;
71                 q1[++t1]=(no){bx,by,p.st+1,k};
72                 ok[bx][by]=1;
73             }
74         }
75     }
76 }
77 void solve(){
78     for(int i=1;i<=n;i++)
79         for(int j=1;j<=m;j++)
80             for(int k=1;k<=4;k++)
81             dis[i][j][k]=inf;
82     pre_white();
83     int ans=inf;
84     while(h2<=t2){
85         no p=q2[h2++];
86         if(dis[p.x][p.y][p.k]!=p.st)continue;
87         if(p.x==tx&&p.y==ty){
88             ans=min(ans,p.st);
89             continue;
90         }
91         for(int k=1;k<=4;k++){
92             int bx=p.x+cc[k][0],by=p.y+cc[k][1];
93             if(k==der[p.k]||!mp[bx][by])continue;
94             int wi=step[p.x][p.y][der[p.k]][k];
95             if(wi<=0)continue;//说明此格子走不过来
96             if(dis[bx][by][k]>dis[p.x][p.y][p.k]+wi+1){//带方向变量的SPFA
97                 dis[bx][by][k]=dis[p.x][p.y][p.k]+wi+1;
98                 q2[++t2]=(no){bx,by,dis[bx][by][k],k};
99             }
100         }
101     }
102     if(ans>=inf||ans<=0)printf("-1\n");
103     else printf("%d\n",ans);
104 }
105 int main(){
107     for(int i=1;i<=n;i++)
108         for(int j=1;j<=m;j++)
110         for(int i=1;i<=n;i++)
111             for(int j=1;j<=m;j++)
112             if(mp[i][j])pre(i,j);
113     while(q--){
119 }