• [弱校联萌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
    ", 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
    ",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
    ", query(1,1,n,l,r).s[0].y);
    62       }
    63   }
    64   return 0;
    65 }
    A
  • 相关阅读:
    进程总结
    三大流程
    canvas简介
    时钟
    vim
    马拉车
    模拟退火
    洛谷P2055假期的宿舍
    洛谷P2320鬼谷子的钱袋.
    洛谷P2278操作系统
  • 原文地址:https://www.cnblogs.com/kirai/p/5932593.html
Copyright © 2020-2023  润新知