Wikioi 3285 转圈游戏
题目描述 Description
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 号小伙伴最后走到了第几号位置。
输入描述 Input Description
输入共 1 行,包含 4 个整数 n、m、k、x,每两个整数之间用一个空格隔开。
输出描述 Output Description
输出共 1 行,包含 1 个整数,表示 10^k 轮后 x 号小伙伴所在的位置编号。
样例输入 Sample Input
10 3 4 5
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
对于 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。
思路:
游戏结束后x号的位置是(x + m*10^k) % n,其中10^k使用快速幂,原理就是10^m * 10^n = 10^(m+n)
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 typedef long long LL; 5 int i,n,m,k,x; 6 LL qmul (int p,int k){ 7 LL temp = p,s = 1; 8 while(k != 0){ 9 if(k%2 == 1) 10 s = (s*(temp%n)) % n; 11 temp = (temp * temp) % n; 12 k = k/2; 13 } 14 return s; 15 } 16 int main(){ 17 long long int turn = 1; 18 scanf("%d",&n); 19 scanf("%d",&m); 20 scanf("%d",&k); 21 scanf("%d",&x); 22 turn = (m*qmul(10,k)+x)%n; 23 printf("%lld",turn); 24 return 0; 25 }
Wikioi 3728 联合权值
题目描述 Description
输入描述 Input Description
输出描述 Output Description
样例输入 Sample Input
样例输出 Sample Output
数据范围及提示 Data Size & Hint
思路:
1、以每一个点为轴,左右两个点算权值
1、以每一个点为轴,左右两个点算权值
2、注意加法结合律(a+b+c)2 = a2 + b2 + c2 + 2ab + 2ac + 2bc
3、取模问题,(a+b)%c ≠ (a%c + b%c)%c,(a + b) % c = (a + b%c)%c
代码:
(注意链式前向星的使用)
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 const int maxn =400020; 5 struct edge{ 6 int next; 7 int to; 8 int power; 9 }; 10 edge test[maxn]; 11 int head[maxn],cur = 0,n,j[maxn],p[maxn],max1[maxn],max2[maxn],nmax1[maxn],coun[maxn]; 12 long long int vall = 0,vmax = 0,sub =0; 13 14 int use(int i) 15 { 16 int t=head[i]; 17 int ti,tmp,sum=0,cha2=0; 18 19 while (t!=-1) 20 { ti=test[t].to; 21 sum=(sum+p[ti]%10007)%10007; 22 cha2+=p[ti]*p[ti]%10007; 23 if (p[ti]>max1[i] ) 24 { max1[i]=p[ti]; 25 nmax1[i]=ti; 26 } 27 t=test[t].next; 28 coun[i]++; 29 30 } 31 sum=(sum*sum%10007 +10007-cha2%10007)%10007; 32 vall+=sum%10007; 33 return sum; 34 } 35 36 /*int dfs(int deep,int last,int now){ 37 if(deep == 2){ 38 if(last == now) return 0; 39 int temp; 40 temp = p[now]* p[last]; 41 if(temp > vmax) vmax = temp; 42 return 0; 43 } 44 45 for(int k=head[now];k>-1;k=test[k].next){ 46 dfs(deep + 1,last,test[k].to); 47 } 48 } */ 49 void dfs(int i) 50 { int ansi=1; 51 if (coun[i]>1) 52 { 53 int t=head[i]; 54 int ti; 55 while (t!=-1) 56 { 57 ti=test[t].to; 58 if (ti!=nmax1[i] ) 59 { 60 if (p[ti]>max2[i] ) 61 max2[i]=p[ti];} 62 t=test[t].next; 63 } 64 } 65 if (vmax<max1[i]*max2[i] ) vmax=max1[i]*max2[i]; 66 67 } 68 69 void add(int u,int v,int w){ 70 test[cur].power = w; 71 test[cur].to = v; 72 test[cur].next = head[u]; 73 head[u] = cur++; 74 } 75 int main(){ 76 cin>>n; 77 int u,v,w; 78 for(int i = 0;i < n;i++){ 79 test[i].power = 1; 80 test[i].next = -1; 81 head[i] = -1; 82 j[i] = 1; 83 } 84 int tu,tv; 85 for(int i = 0;i < n-1;i++){ 86 cin>>tu>>tv; 87 tu--; 88 tv--; 89 add(tu,tv,1); 90 add(tv,tu,1); 91 92 } 93 for(int i = 0;i < n;i++) cin>>p[i]; 94 95 for(int i = 0;i < n;i++)use(i); 96 for(int i = 0;i < n;i++)dfs(i); 97 cout<<vmax<<" "<<vall % 10007<<endl; 98 return 0; 99 }