1002. [FJOI2007]轮状病毒找规律+递推

Posted Refun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1002. [FJOI2007]轮状病毒找规律+递推相关的知识,希望对你有一定的参考价值。

Description

  轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子
和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示

技术分享图片

  N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不
同的3轮状病毒,如下图所示

技术分享图片
  现给定n(N<=100),编程计算有多少个不同的n轮状病毒

Input

  第一行有1个正整数n

Output

  计算出的不同的n轮状病毒数输出

Sample Input

3

Sample Output

16
 
数论推个P,打表找规律
emmm听说这个题要用矩阵树定理……我不会啊……
然后我就去找题解想学一下……然后就看到了一篇找规律的题解……
f[1]=1,f[2]=3,答案就是斐波那契数列的第n项的平方,如果n是偶数还要再减4
高精度都懒得打了……直接搬了一个
啥?矩阵树?以后再说吧
 
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <string>
  6 #include <algorithm>
  7 using namespace std;
  8 
  9 const int MAXN = 410;
 10 
 11 struct bign
 12 {
 13     int len, s[MAXN];
 14     bign ()
 15     {
 16         memset(s, 0, sizeof(s));
 17         len = 1;
 18     }
 19     bign (int num) { *this = num; }
 20     bign (const char *num) { *this = num; }
 21     bign operator = (const int num)
 22     {
 23         char s[MAXN];
 24         sprintf(s, "%d", num);
 25         *this = s;
 26         return *this;
 27     }
 28     bign operator = (const char *num)
 29     {
 30         for(int i = 0; num[i] == 0; num++) ;  //去前导0
 31         len = strlen(num);
 32         for(int i = 0; i < len; i++) s[i] = num[len-i-1] - 0;
 33         return *this;
 34     }
 35     bign operator + (const bign &b) const //+
 36     {
 37         bign c;
 38         c.len = 0;
 39         for(int i = 0, g = 0; g || i < max(len, b.len); i++)
 40         {
 41             int x = g;
 42             if(i < len) x += s[i];
 43             if(i < b.len) x += b.s[i];
 44             c.s[c.len++] = x % 10;
 45             g = x / 10;
 46         }
 47         return c;
 48     }
 49     bign operator += (const bign &b)
 50     {
 51         *this = *this + b;
 52         return *this;
 53     }
 54     void clean()
 55     {
 56         while(len > 1 && !s[len-1]) len--;
 57     }
 58     bign operator * (const bign &b) //*
 59     {
 60         bign c;
 61         c.len = len + b.len;
 62         for(int i = 0; i < len; i++)
 63         {
 64             for(int j = 0; j < b.len; j++)
 65             {
 66                 c.s[i+j] += s[i] * b.s[j];
 67             }
 68         }
 69         for(int i = 0; i < c.len; i++)
 70         {
 71             c.s[i+1] += c.s[i]/10;
 72             c.s[i] %= 10;
 73         }
 74         c.clean();
 75         return c;
 76     }
 77     bign operator *= (const bign &b)
 78     {
 79         *this = *this * b;
 80         return *this;
 81     }
 82     bign operator - (const bign &b)
 83     {
 84         bign c;
 85         c.len = 0;
 86         for(int i = 0, g = 0; i < len; i++)
 87         {
 88             int x = s[i] - g;
 89             if(i < b.len) x -= b.s[i];
 90             if(x >= 0) g = 0;
 91             else
 92             {
 93                 g = 1;
 94                 x += 10;
 95             }
 96             c.s[c.len++] = x;
 97         }
 98         c.clean();
 99         return c;
100     }
101     bign operator -= (const bign &b)
102     {
103         *this = *this - b;
104         return *this;
105     }
106     bign operator / (const bign &b)
107     {
108         bign c, f = 0;
109         for(int i = len-1; i >= 0; i--)
110         {
111             f = f*10;
112             f.s[0] = s[i];
113             while(f >= b)
114             {
115                 f -= b;
116                 c.s[i]++;
117             }
118         }
119         c.len = len;
120         c.clean();
121         return c;
122     }
123     bign operator /= (const bign &b)
124     {
125         *this  = *this / b;
126         return *this;
127     }
128     bign operator % (const bign &b)
129     {
130         bign r = *this / b;
131         r = *this - r*b;
132         return r;
133     }
134     bign operator %= (const bign &b)
135     {
136         *this = *this % b;
137         return *this;
138     }
139     bool operator < (const bign &b)
140     {
141         if(len != b.len) return len < b.len;
142         for(int i = len-1; i >= 0; i--)
143         {
144             if(s[i] != b.s[i]) return s[i] < b.s[i];
145         }
146         return false;
147     }
148     bool operator > (const bign &b)
149     {
150         if(len != b.len) return len > b.len;
151         for(int i = len-1; i >= 0; i--)
152         {
153             if(s[i] != b.s[i]) return s[i] > b.s[i];
154         }
155         return false;
156     }
157     bool operator == (const bign &b)
158     {
159         return !(*this > b) && !(*this < b);
160     }
161     bool operator != (const bign &b)
162     {
163         return !(*this == b);
164     }
165     bool operator <= (const bign &b)
166     {
167         return *this < b || *this == b;
168     }
169     bool operator >= (const bign &b)
170     {
171         return *this > b || *this == b;
172     }
173     string str() const
174     {
175         string res = "";
176         for(int i = 0; i < len; i++) res = char(s[i]+0) + res;
177         return res;
178     }
179 };
180 
181 istream& operator >> (istream &in, bign &x)
182 {
183     string s;
184     in >> s;
185     x = s.c_str();
186     return in;
187 }
188 
189 ostream& operator << (ostream &out, const bign &x)
190 {
191     out << x.str();
192     return out;
193 }
194 
195 bign a,b;
196 int n;
197 
198 int main()
199 {
200     scanf("%d",&n);
201     if (n==1){printf("1"); return 0;}
202     if (n==2){printf("5"); return 0;}
203     a=1,b=3;
204     for (int i=3;i<=n;++i)
205     {
206         a=a+b;
207         swap(a,b);
208     }
209     if (n%2==1) b=b*b;
210     else b=b*b-4;
211     cout<<b;
212 }

以上是关于1002. [FJOI2007]轮状病毒找规律+递推的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1002 [FJOI2007]轮状病毒——打表找规律

BZOJ1002 FJOI2007 轮状病毒 递推

BZOJ 1002 [FJOI2007]轮状病毒

BZOJ 1002: [FJOI2007]轮状病毒

BZOJ1002: [FJOI2007]轮状病毒

[Bzoj]1002: [FJOI2007]轮状病毒