noip2013day1题解
描述
n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏。按照顺时针方向给 n 个位置编号,从0 到 n-1。最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置,……,依此类推。
游戏规则如下:每一轮第 0 号位置上的小伙伴顺时针走到第 m 号位置,第 1 号位置小伙伴走到第 m+1 号位置,……,依此类推,第n − m号位置上的小伙伴走到第 0 号位置,第n-m+1 号位置上的小伙伴走到第 1 号位置,……,第 n-1 号位置上的小伙伴顺时针走到第m-1 号位置。
现在,一共进行了 10^k 轮,请问 x 号小伙伴最后走到了第几号位置。
格式
输入格式
输入共 1 行,包含 4 个整数 n、m、k、x,每两个整数之间用一个空格隔开。
输出格式
输出共 1 行,包含 1 个整数,表示 10^k 轮后 x 号小伙伴所在的位置编号。
限制
每个测试点1s。
提示
对于 30%的数据,0 < k < 7;
对于 80%的数据,0 < k < 10^7;
对于 100%的数据,1 < n < 1,000,000,0 < m < n,1 <= x <=n,0 < k < 10^9。
推一推发现是快速幂裸题
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 int n,m,k,x; 5 6 int power(int now) 7 { 8 if(now==0)return 1; 9 int t=power(now/2); 10 t=(t*t)%n; 11 if(now%2!=0)return (t*10)%n; 12 else return t; 13 } 14 15 16 int main() 17 { 18 cin>>n>>m>>k>>x; 19 int left=power(k)*m; 20 left%=n; 21 cout<<(left+x)%n; 22 return 0; 23 }
描述
涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:∑i=1n(ai−bi)2∑i=1n(ai−bi)2
,其中 aiai
表示第一列火柴中第 i 个火柴的高度,bibi
表示第二列火柴中第 i 个火柴的高度。
每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果。
格式
输入格式
共三行,第一行包含一个整数 n,表示每盒中火柴的数目。
第二行有 n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。
第三行有 n 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。
输出格式
输出共一行,包含一个整数,表示最少交换次数对 99,999,997 取模的结果。
限制
每个测试点1s。
逆序对,当年的离散化简直exciting
1 #include<stdio.h> 2 #include<iostream> 3 #include<cstdlib> 4 using namespace std; 5 int n,C1[1000000],C2[1000000],A1[1000000],A2[1000000],D1[1000000],tree[1000001]={0},answer=0; 6 long long S1[1000000],S2[1000000]; 7 8 int devide1(int l, int r) 9 { 10 int x=S1[(l+r)/2],i=l-1,j=r+1; 11 while(1) 12 { 13 do{--j;} 14 while(S1[j]>x); 15 16 do{++i;} 17 while(S1[i]<x); 18 19 if(i<j) 20 { 21 long long t=S1[i]; 22 S1[i]=S1[j]; 23 S1[j]=t; 24 t=C1[i]; 25 C1[i]=C1[j]; 26 C1[j]=t; 27 } 28 else return j; 29 } 30 } 31 32 void qsort1(int l,int r) 33 { 34 int p; 35 if(l<r) 36 { 37 p=devide1(l,r); 38 qsort1(l,p); 39 qsort1(p+1,r); 40 } 41 } 42 43 int devide2(int l, int r) 44 { 45 int x=S2[(l+r)/2],i=l-1,j=r+1; 46 while(1) 47 { 48 do{--j;} 49 while(S2[j]>x); 50 51 do{++i;} 52 while(S2[i]<x); 53 54 if(i<j) 55 { 56 long long t=S2[i]; 57 S2[i]=S2[j]; 58 S2[j]=t; 59 t=C2[i]; 60 C2[i]=C2[j]; 61 C2[j]=t; 62 } 63 else return j; 64 } 65 } 66 67 void qsort2(int l,int r) 68 { 69 int p; 70 if(l<r) 71 { 72 p=devide2(l,r); 73 qsort2(l,p); 74 qsort2(p+1,r); 75 } 76 } 77 78 int read(int k) 79 { 80 int sum=0; 81 while(k) 82 { 83 sum+=tree[k]; 84 k-=k&-k; 85 } 86 return sum; 87 } 88 89 void add(int k,int num) 90 { 91 while(k<=n) 92 { 93 tree[k]+=num; 94 k+=k&-k; 95 } 96 } 97 98 int main() 99 { 100 cin>>n; 101 for(int i=0;i<n;i++) 102 cin>>S1[i]; 103 for(int i=0;i<n;i++) 104 { 105 cin>>S2[i]; 106 C1[i]=i; 107 C2[i]=i; 108 } 109 qsort1(0,n-1); 110 qsort2(0,n-1); 111 for(int i=0;i<n;i++) 112 { 113 A1[C1[i]]=i; 114 A2[C2[i]]=i; 115 } 116 for(int i=0;i<n;i++)D1[C1[i]]=C2[i]; 117 118 for(int i=n-1;i>=0;i--) 119 { 120 add(D1[i]+1,1); 121 answer+=(read(D1[i]+1)-1)%99999997; 122 answer%=99999997; 123 } 124 cout<<answer<<endl; 125 return 0; 126 }
描述
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
格式
输入格式
第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。
接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。
输出格式
输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-1。
限制
每个测试点1s。
提示
对于 30%的数据,0 < n < 1,000,0 < m < 10,000,0 < q < 1,000;
对于 60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q < 1,000;
对于 100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q < 30,000,0 ≤ z ≤ 100,000。
最小生成树+树上倍增
1 #include<iostream> 2 #include<string.h> 3 #include<algorithm> 4 #include<stdio.h> 5 #include<cstdlib> 6 #define N 10005 7 #define M 50005 8 #define inf 0x3f3f3f3f 9 using namespace std; 10 int n,m,q; 11 int cnt,tot; 12 int beg[N]; 13 int deep[N]; 14 int set[N]; 15 int father[N][17],ans[N][17]; 16 int vis[N]; 17 18 struct Edge 19 { 20 int a,b,weight; 21 }e[M]; 22 23 struct edge 24 { 25 int b,next,weight; 26 }E[N*2]; 27 28 int addedge(int a,int b,int weight) 29 { 30 E[cnt].b=b; 31 E[cnt].next=beg[a]; 32 beg[a]=cnt; 33 E[cnt].weight=weight; 34 cnt++; 35 E[cnt].b=a; 36 E[cnt].next=beg[b]; 37 beg[b]=cnt; 38 E[cnt].weight=weight; 39 cnt++; 40 } 41 42 int find(int a) 43 { 44 if(set[a]==a) 45 return a; 46 return set[a]=find(set[a]); 47 } 48 49 int connect(int a,int b) 50 { 51 a=find(a),b=find(b); 52 set[a]=b; 53 } 54 55 int cmp(Edge a,Edge b) 56 { 57 return a.weight<b.weight; 58 } 59 60 void rebuilt() 61 { 62 sort(e,e+m,cmp); 63 while(m>0) 64 { 65 if(find(e[m-1].a)!=find(e[m-1].b)) 66 { 67 addedge(e[m-1].a-1,e[m-1].b-1,e[m-1].weight); 68 connect(e[m-1].a,e[m-1].b); 69 } 70 m--; 71 } 72 } 73 74 void DFS(int x) 75 { 76 vis[x]=1; 77 for(int i=1;i<17;i++) 78 { 79 if(deep[x]<(1<<i))break; 80 father[x][i]=father[father[x][i-1]][i-1]; 81 ans[x][i]=min(ans[x][i-1],ans[father[x][i-1]][i-1]); 82 } 83 for(int i=beg[x];i!=-1;i=E[i].next) 84 { 85 if(vis[E[i].b]==1)continue; 86 father[E[i].b][0]=x; 87 ans[E[i].b][0]=E[i].weight; 88 deep[E[i].b]=deep[x]+1; 89 DFS(E[i].b); 90 } 91 } 92 93 int lca(int a,int b) 94 { 95 if(deep[a]<deep[b]) 96 swap(a,b); 97 int t=deep[a]-deep[b]; 98 for(int i=0;i<17;i++) 99 if((1<<i)&t) 100 a=father[a][i]; 101 for(int i=16;i>=0;i--) 102 if(father[a][i]!=father[b][i]) 103 { 104 a=father[a][i]; 105 b=father[b][i]; 106 } 107 if(a==b)return a; 108 return father[a][0]; 109 } 110 111 int ask(int a,int b) 112 { 113 int ret=inf; 114 int t=deep[a]-deep[b]; 115 for(int i=0;i<17;i++) 116 { 117 if(t&(1<<i)) 118 { 119 ret=min(ret,ans[a][i]); 120 a=father[a][i]; 121 } 122 } 123 return ret; 124 } 125 126 int main() 127 { 128 int a,b; 129 memset(beg,-1,sizeof(beg)); 130 scanf("%d%d",&n,&m); 131 for(int i=0;i<=n;i++) 132 set[i]=i; 133 for(int i=0;i<m;i++) 134 scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].weight); 135 rebuilt(); 136 for(int i=0;i<n;i++) 137 if(vis[i]==0) 138 DFS(i); 139 scanf("%d",&q); 140 for(int i=0;i<q;i++) 141 { 142 scanf("%d%d",&a,&b); 143 if(find(a)!=find(b)) 144 { 145 printf("-1\n"); 146 continue; 147 } 148 else 149 { 150 a--,b--; 151 int t=lca(a,b); 152 printf("%d\n",min(ask(a,t),ask(b,t))); 153 } 154 } 155 return 0; 156 }