数学——大整数问题

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 }
View Code

 Wikioi 3728 联合权值

题目描述 Description

输入描述 Input Description

输出描述 Output Description

blob.png

样例输入 Sample Input

样例输出 Sample Output

数据范围及提示 Data Size & Hint

思路:
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 }
View Code
posted @ 2015-09-27 08:42  ACforever  阅读(236)  评论(0编辑  收藏  举报