[弱校联萌2016]2016弱校联盟十一专场10.5

比赛链接:https://www.bnuoj.com/v3/contest_show.php?cid=8506#info

I.裸数位dp,dp[l][pre][dir][fz]表示长度为l的时候上一个数是pre,此时是统计dir(分为增、减、相同),fz记录当前是否是前导零。有种情况,就是各位相同的情况,要减掉。

ps:其实不用fz这一维,删掉就行了,智障了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int maxn = 22;
 6 // l, pre, dir, fz
 7 int dp[maxn][11][3][2];
 8 int digit[maxn];
 9 LL l, r;
10 
11 LL dfs(int l, int pre, int dir, bool fz, bool flag) {
12   if(l == 0) return 1;
13   if(!flag && ~dp[l][pre][dir][fz]) return dp[l][pre][dir][fz];
14   LL ret = 0;
15   int pos = flag ? digit[l] : 9;
16   for(int i = 0; i <= pos; i++) {
17     if(fz&&(i==0)) ret += dfs(l-1,pre,dir,fz,flag&&(i==pos));
18     else {
19       if(dir==1) {
20         if(i>=pre) ret += dfs(l-1,i,dir,fz&&(i==0),flag&&(i==pos));
21       }
22       else if(dir == 0) {
23         if(i<=pre) ret += dfs(l-1,i,dir,fz&&(i==0),flag&&(i==pos));
24       }
25       else if(dir == 2) {
26         if(i==pre||(pre==10&&i)) ret += dfs(l-1,i,dir,fz&&(i==0),flag&&(i==pos));
27       }
28     }
29   }
30   if(!flag) dp[l][pre][dir][fz] = ret;
31   return ret;
32 }
33 
34 LL f(LL x) {
35   int pos = 0;
36   while(x) {
37     digit[++pos] = x % 10;
38     x /= 10;
39   }
40   return dfs(pos,10,0,true,true)+dfs(pos,0,1,true,true)-dfs(pos,10,2,true,true);
41 }
42 
43 inline bool scan_d(LL &num) {
44     char in;bool IsN=false;
45     in=getchar();
46     if(in==EOF) return false;
47     while(in!='-'&&(in<'0'||in>'9')) in=getchar();
48     if(in=='-'){ IsN=true;num=0;}
49     else num=in-'0';
50     while(in=getchar(),in>='0'&&in<='9'){
51         num*=10,num+=in-'0';
52     }
53     if(IsN) num=-num;
54     return true;
55 }
56 
57 int main() {
58   // freopen("in", "r", stdin);
59   memset(dp, -1, sizeof(dp));
60   int T;
61   scanf("%d", &T);
62   while(T--) {
63     scan_d(l); scan_d(r);
64     printf("%lld\n", f(r)-f(l-1));
65   }
66   return 0;
67 }
I

F.矩阵快速幂就可以,先找斐波那契数列在%20160516下的循环节,求出fib对应下标再求一遍。参考了这个http://blog.csdn.net/tsoi_vergil/article/details/52718426

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int maxn = 5;
 6 const LL mod = 20160519;
 7 const LL mod1 = 26880696;
 8 int n;
 9 
10 typedef struct Matrix {
11     LL m[maxn][maxn];
12     int r;
13     int c;
14     Matrix(){
15         r = c = 0;
16         memset(m, 0, sizeof(m));
17     }
18 } Matrix;
19 
20 Matrix mul(Matrix m1, Matrix m2, LL mod) {
21     Matrix ans = Matrix();
22     ans.r = m1.r;
23     ans.c = m2.c;
24     for(int i = 1; i <= m1.r; i++) {
25         for(int j = 1; j <= m2.r; j++) {
26                  for(int k = 1; k <= m2.c; k++) {
27                 if(m2.m[j][k] == 0) continue;
28                 ans.m[i][k] = ((ans.m[i][k] + m1.m[i][j] * m2.m[j][k] % mod) % mod) % mod;
29             }
30         }
31     }
32     return ans;
33 }
34 
35 Matrix quickmul(Matrix m, int n, LL mod) {
36     Matrix ans = Matrix();
37     for(int i = 1; i <= m.r; i++) {
38         ans.m[i][i]  = 1LL;
39     }
40     ans.r = m.r;
41     ans.c = m.c;
42     while(n) {
43         if(n & 1) {
44             ans = mul(m, ans, mod);
45         }
46         m = mul(m, m, mod);
47         n >>= 1;
48     }
49     return ans;
50 }
51 
52 int main() {
53     //freopen("in", "r", stdin);
54     int T;
55     scanf("%d", &T);
56     while(T--) {
57         scanf("%d",&n);
58         Matrix A; A.c = A.r = 2;
59         A.m[1][1] = 1; A.m[1][2] = 1; A.m[2][1] = 1; A.m[2][2] = 0;
60         Matrix B; B.c = B.r = 2;
61         B = quickmul(A,n,mod1);
62         n = B.m[1][2];
63         A.m[1][1] = 1; A.m[1][2] = 1; A.m[2][1] = 1; A.m[2][2] = 0;
64         B = quickmul(A,n,mod);
65         printf("%lld\n",B.m[1][2]%mod);
66     }
67     return 0;
68 }
F

 A.用个线段树维护下就可以,也可以离线+倍增。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define lrt rt << 1
 5 #define rrt rt << 1 | 1
 6 const int maxn = 100100;
 7 const int maxm = maxn << 2;
 8 char s[maxn];
 9 int q, n;
10 int asc[256];
11 typedef struct Pair {
12   int x, y;
13   Pair(){}
14   Pair(int x,int y):x(x),y(y){}
15 }Pair;
16 typedef struct Node {
17   Pair s[4];
18   Node() { for(int i = 0; i < 4; i++) s[i].x = i, s[i].y = 0; }
19 }Node;
20 
21 Node sum[maxm];
22 
23 Node f(Node a, Node b) {
24   Node ret;
25   for(int i = 0; i < 4; i++) {
26       int x = b.s[a.s[i].x].x;
27       int y = (a.s[i].x - i + 4) % 4 + (x - a.s[i].x + 4) % 4;
28       ret.s[i] = Pair(x, a.s[i].y+b.s[a.s[i].x].y+(y>=4));
29     }
30   return ret;
31 }
32 void build(int rt, int l, int r) {
33   sum[rt] = Node();
34   if(l == r) {
35       sum[rt].s[asc[s[l]]] = Pair((asc[s[l]]+1)%4, 0);
36       return;
37   }
38   int m = (l + r) >> 1;
39   build(lrt, l, m); build(rrt, m+1, r);
40   sum[rt] = f(sum[lrt], sum[rrt]);
41 }
42 Node query(int rt, int l, int r, int L, int R) {
43     if(L <= l && r <= R) return sum[rt];
44   int m = (l + r) >> 1;
45   if(R <= m) return query(lrt,l,m,L,R);
46   else if(m < L) return query(rrt,m+1,r,L,R);
47   else return f(query(lrt,l,m,L,m), query(rrt,m+1,r,m+1,R));
48 }
49 
50 int main() {
51   //freopen("in","r",stdin);
52   asc['e'] = 0; asc['a'] = 1; asc['s'] = 2; asc['y'] = 3;
53   int l, r;
54   while(~scanf("%s%d",s+1,&q)) {
55       n = strlen(s+1);
56       build(1,1,n);
57       while(q--) {
58         scanf("%d%d",&l,&r);
59         if(l > r) swap(l, r);
60         if(r-l+1<4) puts("0");
61         else printf("%d\n", query(1,1,n,l,r).s[0].y);
62       }
63   }
64   return 0;
65 }
A

 

posted @ 2016-10-05 18:00  Kirai  阅读(200)  评论(0编辑  收藏  举报