杭州邀请赛

hdu 4576

题意:在一个环里从起点随机走c步,一共走m次,问最后站在l~r的概率是多少?

分析:常数优化,想不到就作死。

 1 #include<cstdio>

 2 #include<cstring>

 3 #include<cstdlib>

 4 #include<iostream>

 5 #include<algorithm>

 6 #include<cmath>

 7 #include<vector>

 8 #include<map>

 9 #include<set>

10 #define lson l,m,rt<<1

11 #define rson m+1,r,rt<<1|1

12 #define pbk push_back

13 #define mk make_pair

14 using namespace std;

15 const int N = 10000+10;

16 typedef pair<int,int> pii;

17 typedef long long LL;

18 int n,m,l,r;

19 double dp[2][N];

20 int c[1000000+10],vis[N];

21 const double eps = 1e-10;

22 inline int dcmp(double x){

23     return x < -eps ? -1 : x>eps;

24 }

25 void solve(){

26     memset(dp,0,sizeof(dp));

27     dp[0][1] = 1;

28     int pos = 0;

29     int flag = 0;

30     for (int i = 0; i < m; i++) {

31         for (int j = 1; j <= n; j++) {

32             int v = j + c[i];

33             while (v > n) v -= n;

34             dp[pos^1][j] = dp[pos][v]*0.5;

35             v = j - c[i];

36             while (v <= 0) v += n;

37             dp[pos^1][j] += dp[pos][v]*0.5;

38         }

39         pos ^= 1;

40     }

41     double ret = 0;

42     for (int i = 1; i <= n; i++) {

43         if (i >= l && i <= r)

44         ret += dp[pos][i];

45     }

46     printf("%.4lf\n",ret);

47 }

48 int main(){

49     while (~scanf("%d%d%d%d",&n,&m,&l,&r),n+m+l+r) {

50 

51         for (int i = 0; i < m; i++) {

52             scanf("%d",c+i);

53         }

54         solve();

55     }

56 

57     return 0;

58 }
View Code

 

hdu 4577

题意:1~n个球,给你k个盒子,从第一个盒子开始放,如果第一个盒子放了i,那么下一个盒子一定必须有i*2,一个球只能放一个盒子;

问第一个盒子做的放几个球;

分析:显然n/(pow(2,k-1))后所有奇数都是不会重复的答案,然后考虑偶数情况,如果n/(pow(2,2k-1)),那么对于此时起点是奇数的显然可以统计两次,起点为奇数的已经统计过,

而起点是偶数的显然没有统计过于是统计,依次统计n/(pow(2,jk-1));

例如:   12 2

1 2

2 4

3 6

4 8

5 10

6 12

先统计 (1,2)(3,6)(5,10);

1 2 4 8

统计 (4,8);

 1 import java.util.*;

 2 import java.math.*;

 3 import java.io.*;

 4 

 5 class Work {

 6     public void main(){

 7         Scanner cin = new Scanner(System.in);

 8         int T;

 9         T = cin.nextInt();

10         for (int i = 0; i < T; i++) {

11             BigInteger n = cin.nextBigInteger();

12             int k = cin.nextInt();

13             BigInteger ans = BigInteger.ZERO;

14             BigInteger  p = BigInteger.valueOf(2).pow(k-1);

15             while(true){

16                 n = n.divide(p);

17                 if (n.compareTo(BigInteger.ZERO) == 0) break;

18                 ans = ans.add(n.subtract(n.divide(BigInteger.valueOf(2))));

19                 n = n.divide(BigInteger.valueOf(2));

20             }

21             System.out.println(ans);

22         }

23     }

24 }

25 

26 public class Main {

27     public static void main(String[] args) {

28         Work t = new Work();

29         t.main();

30     }

31 

32 }
View Code

 

 

 

hdu 4578

题意:给你3种操作,询问区间和,和的平方,和的立方;

分析:线段树,分别记录下区间和,和的平方,和的立方;

然后操作分3种要按一定的顺序来pushdown下去,先更新cov标记,然后在更新mul,最后更新add;

当然在update的时候要转化,比如原先已经有了mul和add表示,再来 乘c,就要更新标记 mul*c,add*c

再比如来了操作3,c,就要情况mul和add;具体可以看代码;代码一是本人拙计代码;代码二来自YCL

  1 #include<cstdio>

  2 #include<cstring>

  3 #include<cstdlib>

  4 #include<iostream>

  5 #include<algorithm>

  6 #include<cmath>

  7 #define lson l,m,rt<<1

  8 #define rson m+1,r,rt<<1|1

  9 using namespace std;

 10 const int N = 100000+10;

 11 const int M = 10007;

 12 int sum[4][N<<2];

 13 int c1,c2,c3;

 14 int n,m;

 15 int col[4][N<<2];

 16 void pushdown(int rt,int l, int m,int r) {

 17     int c1,c2,c3;

 18     if (col[2][rt]) {

 19         c1 = col[2][rt] % M; c2 = c1 * c1 % M; c3 = c1 * c2 % M;

 20         sum[3][rt<<1] = (m - l + 1) * c3 % M;

 21         sum[2][rt<<1] = (m - l + 1) * c2 % M;

 22         sum[1][rt<<1] = (m - l + 1) * c1 % M;

 23         sum[3][rt<<1|1] = (r - m) * c3 % M;

 24         sum[2][rt<<1|1] = (r - m) * c2 % M;

 25         sum[1][rt<<1|1] = (r - m) * c1 % M;

 26         col[1][rt<<1] = col[1][rt<<1|1] = 1;

 27         col[0][rt<<1] = col[0][rt<<1|1] = 0;

 28         col[2][rt<<1] = col[2][rt<<1|1] = col[2][rt] % M;

 29         col[2][rt] = 0;

 30     }

 31     c1 = col[1][rt] % M; c2 = c1 * c1 % M; c3 = c1 * c2 % M;

 32 

 33     sum[3][rt<<1] = ( sum[3][rt<<1] * c3 ) % M;

 34     sum[2][rt<<1] = ( sum[2][rt<<1] * c2 ) % M;

 35     sum[1][rt<<1] = ( sum[1][rt<<1] * c1 ) % M;

 36     sum[3][rt<<1|1] = ( sum[3][rt<<1|1] * c3 ) % M;

 37     sum[2][rt<<1|1] = ( sum[2][rt<<1|1] * c2 ) % M;

 38     sum[1][rt<<1|1] = ( sum[1][rt<<1|1] * c1 ) % M;

 39     c1 = col[0][rt] % M; c2 = c1 * c1 % M; c3 = c1 * c2 % M;

 40     sum[3][rt<<1] = ( sum[3][rt<<1] + 3*c1*sum[2][rt<<1] + 3*c2*sum[1][rt<<1] + (m-l+1)*c3 ) % M;

 41     sum[2][rt<<1] = ( sum[2][rt<<1] + 2*c1*sum[1][rt<<1] + (m-l+1)*c2 ) % M;

 42     sum[1][rt<<1] = ( sum[1][rt<<1] + (m-l+1)*c1 ) % M;

 43 

 44     sum[3][rt<<1|1] = ( sum[3][rt<<1|1] + 3*c1*sum[2][rt<<1|1] + 3*c2*sum[1][rt<<1|1] + (r-m)*c3 ) % M;

 45     sum[2][rt<<1|1] = ( sum[2][rt<<1|1] + 2*c1*sum[1][rt<<1|1] + (r-m)*c2 ) % M;

 46     sum[1][rt<<1|1] = ( sum[1][rt<<1|1] + (r-m)*c1 ) % M;

 47 

 48     col[1][rt<<1] = (col[1][rt<<1] * col[1][rt]) % M;

 49     col[1][rt<<1|1] = (col[1][rt<<1|1] * col[1][rt]) % M;

 50     col[0][rt<<1] = (col[0][rt<<1] * col[1][rt] + col[0][rt]) % M;

 51     col[0][rt<<1|1] = (col[0][rt<<1|1] * col[1][rt] + col[0][rt] ) % M;

 52     col[0][rt] = 0; col[1][rt] = 1;

 53 

 54 }

 55 void pushup(int rt) {

 56     for (int i = 1; i <= 3; i++) {

 57         sum[i][rt] = (sum[i][rt<<1] + sum[i][rt<<1|1]) % M;

 58     }

 59 }

 60 void update(int L,int R,int op,int c,int l,int r,int rt) {

 61     if (L <= l && r <= R) {

 62         if (op == 1) {

 63             sum[3][rt] = ( sum[3][rt] + 3*c1*sum[2][rt] + 3*c2*sum[1][rt] + (r-l+1)*c3 ) % M;

 64             sum[2][rt] = ( sum[2][rt] + 2*c1*sum[1][rt] + (r-l+1)*c2 ) % M;

 65             sum[1][rt] = ( sum[1][rt] + (r-l+1)*c1 ) % M;

 66             col[0][rt] = (col[0][rt] + c1 ) % M;

 67         }else if ( op == 2) {

 68             sum[3][rt] = ( sum[3][rt] * c3 ) % M;

 69             sum[2][rt] = ( sum[2][rt] * c2 ) % M;

 70             sum[1][rt] = ( sum[1][rt] * c1 ) % M;

 71             col[0][rt] = ( col[0][rt] * c1 ) % M;

 72             col[1][rt] = ( col[1][rt] * c1 ) % M;

 73 

 74         }else if ( op == 3) {

 75             sum[3][rt] = (r - l + 1) * c3 % M;

 76             sum[2][rt] = (r - l + 1) * c2 % M;

 77             sum[1][rt] = (r - l + 1) * c1 % M;

 78 

 79             col[2][rt] = c1 % M;

 80             col[0][rt] = 0; col[1][rt] = 1;

 81 

 82         }

 83         return;

 84     }

 85     int m = (l+r) >> 1;

 86     pushdown(rt,l,m,r);

 87     if (L <= m) update(L,R,op,c,lson);

 88     if (m <  R) update(L,R,op,c,rson);

 89     pushup(rt);

 90 }

 91 

 92 int query(int L,int R,int c,int l,int r,int rt) {

 93     if (L <= l && r <= R) {

 94         return sum[c][rt];

 95     }

 96     int m = (l+r) >> 1;

 97     pushdown(rt,l,m,r);

 98     int t1 = 0, t2 = 0 ;

 99     if (L <= m) t1 = query(L,R,c,lson);

100     if (m < R ) t2 = query(L,R,c,rson);

101     return (t1+t2) % M;

102 }

103 int main(){

104     while (~scanf("%d%d",&n,&m),n+m) {

105         memset(sum,0,sizeof(sum));

106         memset(col,0,sizeof(col));

107         for (int i = 0; i <= (n<<2); i++) col[1][i] = 1;

108         for (int i = 0; i < m; i++) {

109             int op,l,r,c;

110             scanf("%d%d%d%d",&op,&l,&r,&c);

111             c1 = c % M; c2 = c1 * c1 % M; c3 = c1 * c2 % M;

112             if (op == 1) {

113                 update(l,r,op,c,1,n,1);

114             }else if (op == 2) {

115                 update(l,r,op,c,1,n,1);

116             }else if (op == 3) {

117                 update(l,r,op,c,1,n,1);

118             }else if (op == 4) {

119                 printf("%d\n",query(l,r,c,1,n,1));

120             }

121         }

122     }

123     return 0;

124 }
View Code
  1 #include <cstdio>

  2 #include <cstring>

  3 #include <algorithm>

  4 using namespace std;

  5 

  6 #define lch (rt<<1)

  7 #define rch (rt<<1|1)

  8 

  9 const int N = 100010;

 10 const int mod = 10007;

 11 

 12 int s[4][N<<2];

 13 int mul[N<<2], add[N<<2], cov[N<<2];

 14 

 15 void build(int l, int r, int rt) {

 16     for (int i = 1; i <= 3; i++) s[i][rt] = 0;

 17     mul[rt] = 1; cov[rt] = add[rt] = 0;

 18     if (l == r) return;

 19     int m = (l + r) >> 1;

 20     build(l, m, lch);

 21     build(m + 1, r, rch);

 22 }

 23 

 24 void pushup(int rt) {

 25     for (int i = 1; i <= 3; i++)

 26         s[i][rt] = (s[i][lch] + s[i][rch]) % mod;

 27 }

 28 

 29 void maintain(int x, int k, int l, int r, int rt) {

 30     int len = r - l + 1;

 31     if (k == 3) {

 32         s[3][rt] = x * x % mod * x % mod * len % mod;

 33         s[2][rt] = x * x % mod * len % mod;

 34         s[1][rt] = x * len % mod;

 35         cov[rt] = x;

 36         mul[rt] = 1;

 37         add[rt] = 0;

 38     } else if (k == 2) {

 39         s[3][rt] = s[3][rt] * x % mod * x % mod * x % mod;

 40         s[2][rt] = s[2][rt] * x % mod * x % mod;

 41         s[1][rt] = s[1][rt] * x % mod;

 42         mul[rt] = mul[rt] * x % mod;

 43         add[rt] = add[rt] * x % mod;

 44     } else {

 45         s[3][rt] = (s[3][rt] + x * x % mod * x % mod * len % mod + 3 * s[2][rt] * x % mod + 3 * s[1][rt] * x % mod * x % mod) % mod;

 46         s[2][rt] = (s[2][rt] + x * x % mod * len % mod + 2 * x * s[1][rt] % mod) % mod;

 47         s[1][rt] = (s[1][rt] + x * len) % mod;

 48         add[rt] = (add[rt] + x) % mod;

 49     }

 50 }

 51 

 52 void pushdown(int l, int r, int rt) {

 53     int m = (l + r) >> 1;

 54     if (cov[rt]) {

 55         maintain(cov[rt], 3, l, m, lch);

 56         maintain(cov[rt], 3, m + 1, r, rch);

 57         cov[rt] = 0;

 58     }

 59     if (mul[rt] != 1) {

 60         maintain(mul[rt], 2, l, m, lch);

 61         maintain(mul[rt], 2, m + 1, r, rch);

 62         mul[rt] = 1;

 63     }

 64     if (add[rt] != 0) {

 65         maintain(add[rt], 1, l, m, lch);

 66         maintain(add[rt], 1, m + 1, r, rch);

 67         add[rt] = 0;

 68     }

 69 }

 70 

 71 void update(int ql, int qr, int x, int k, int l, int r, int rt) {

 72     if (ql <= l && r <= qr) {

 73         maintain(x, k, l, r, rt);

 74         return;

 75     }

 76     pushdown(l, r, rt);

 77     int m = (l + r) >> 1;

 78     if (ql <= m) update(ql, qr, x, k, l, m, lch);

 79     if (qr > m) update(ql, qr, x, k, m + 1, r, rch);

 80     pushup(rt);

 81 }

 82 

 83 int query(int ql, int qr, int k, int l, int r, int rt) {

 84     if (ql <= l && r <= qr) return s[k][rt];

 85     pushdown(l, r, rt);

 86     int m = (l + r) >> 1;

 87     int res = 0;

 88     if (ql <= m) res += query(ql, qr, k, l, m, lch);

 89     if (qr > m) res += query(ql, qr, k, m + 1, r, rch);

 90     return res % mod;

 91 }

 92 

 93 int main() {

 94     int n, m;

 95     while (scanf("%d%d", &n, &m), n || m) {

 96         build(1, n, 1);

 97         for (int i = 0; i < m; i++) {

 98             int op, x, y, c;

 99             scanf("%d%d%d%d", &op, &x, &y, &c);

100             if (op < 4) {

101                 update(x, y, c, op, 1, n, 1);

102             } else {

103                 int ans = query(x, y, c, 1, n, 1);

104                 printf("%d\n", ans);

105             }

106         }

107     }

108     return 0;

109 }
View Code

 

 hdu 4579

题意:从1走到n点的期望是多少,告诉你p[i,j]即,在点i走到j的概率;

分析:很标准的概率DP,然后列出方程,然后发现可以迭代消圆,一路搞下去就可以了;

设dp[i]表示在i点到达目标点的期望,那么dp[i] = sum(p[i,j]*dp[j] ) +1; (j是从i可以到达的点)

样例5 2 1 2 2 1 3 2 2 3 1 3

dp[5] = 0;  (1)

dp[4] = p[4,2] * dp[2]  + p[4,3] * dp[3] + p[4,4] * dp[4] + p[4,5] * dp[5] + 1;   (2)

dp[3] = p[] * dp[1] + p[] * dp[2] + p[] * dp[3] + p[] * dp[4] + p[] * dp[5] + 1;    (3)

dp[2] = p[] * dp[1] + p[] * dp[2] + p[] * dp[3] + p[] * dp[4] + 1;                       (4)

dp[1] = p[] * dp[1] + p[] * dp[2] + p[] * dp[3]  + 1;                                         (5)

从上到下迭代,把方程(1)带入(2)  则dp[4] 可以表示成  a*dp[2] + b * dp[3] + c;

把dp[4] 和dp[5]一起带入(3)中  则dp[3] 可以表示成 d*dp[1] + e * dp[2] + f;

这样一直迭代下去,最终就是dp[1] = g  ;

 1 #include<cstdio>

 2 #include<cstring>

 3 #include<cstdlib>

 4 #include<iostream>

 5 #include<algorithm>

 6 #include<cmath>

 7 #include<vector>

 8 #include<map>

 9 #include<set>

10 #define lson l,m,rt<<1

11 #define rson m+1,r,rt<<1|1

12 #define pbk push_back

13 #define mk make_pair

14 using namespace std;

15 const int N = 50000+10;

16 typedef pair<int,int> pii;

17 typedef long long LL;

18 int n,m;

19 int c[N][7];

20 int sum[N];

21 double w[N][7];

22 double p[15];

23 double dp[N];

24 void solve(){

25     memset(w,0,sizeof(w));

26     memset(dp,0,sizeof(dp));

27     dp[n] = 0;

28     for (int i = n-1; i >= 1; i--) {

29         int cnt = 0;

30         double tmp = 0;

31         memset(p,0,sizeof(p));

32         for (int j = max(1,i-m); j <= min(n,i+m); j++){

33             if (i == j) continue;

34             if (i > j) p[ j-i+m+1 ] = 0.3*c[i][i-j]/(1+sum[i]);

35             else if (i < j) p[ j-i+m+1 ] = 0.7*c[i][j-i]/(1+sum[i]);

36             tmp += p[ j-i+m+1 ];

37         }

38         p[m+1] = 1- tmp;

39         p[0] = 1;

40         for (int j = i+m ; j > i; j--) {

41             if (j >= n) continue;

42             for (int k = m,c1 = 1; k > 0; k--,c1++) {

43                 p[ j-i+m+1 - c1] += p[ j-i+m+1 ]*w[j][k];

44             }

45             p[0] += p[ j-i+m+1 ]*w[j][0];

46         }

47         double tp = 1 - p[m+1];

48         for (int j = 0; j <= m; j++) {

49             w[i][j] = p[j]/tp;

50         }

51     }

52     printf("%.2lf\n",w[1][0]);

53 

54 }

55 int main(){

56     while (~ scanf("%d%d",&n,&m),n+m) {

57         for (int i = 1; i <= n; i++) {

58             sum[i] = 0;

59             for (int  j = 1; j <= m; j++){

60                 scanf("%d",&c[i][j]);

61                 sum[i] += c[i][j];

62             }

63         }

64         solve();

65     }

66     return 0;

67 }
View Code

 

 hdu 4584

题意:找最近的H和C;

分析:暴力找;

 1 #include<cstdio>

 2 #include<cstring>

 3 #include<cstdlib>

 4 #include<iostream>

 5 #include<algorithm>

 6 #include<cmath>

 7 #include<vector>

 8 #include<map>

 9 #include<set>

10 #define lson l,m,rt<<1

11 #define rson m+1,r,rt<<1|1

12 #define pbk push_back

13 #define mk make_pair

14 using namespace std;

15 const int N = 10000+10;

16 typedef pair<int,int> pii;

17 typedef long long LL;

18 char mz[50][50];

19 int n,m;

20 int sx,sy,ex,ey;

21 int d;

22 void find(int x,int y){

23     for (int  i = 0; i < n; i++) {

24         for (int j = 0; j < m; j++) {

25             if (mz[i][j] == 'C') {

26                 int td = abs(x-i) + abs(y-j);

27                 if (td < d) {

28                     sx = x; sy = y;

29                     ex = i; ey =j;

30                     d = td;

31                 }

32             }

33         }

34     }

35 }

36 int main(){

37     while (~scanf("%d%d",&n,&m),n+m) {

38         for (int i = 0; i < n; i++) {

39             scanf("%s",mz[i]);

40         }

41         d = n*m + 10;

42         sx = sy = ex = ey = -1;

43         for (int i = 0; i < n; i++) {

44             for (int j = 0; j < m; j++) {

45                 if (mz[i][j] == 'H') {

46                     find(i,j);

47                 }

48             }

49         }

50         printf("%d %d %d %d\n",sx,sy,ex,ey);

51     }

52 

53     return 0;

54 }
View Code

 

hdu 4585

题意:依次插入n个数,找前面离它最近的数

分析:用set直接找;

 1 #include<cstdio>

 2 #include<cstring>

 3 #include<cstdlib>

 4 #include<iostream>

 5 #include<algorithm>

 6 #include<cmath>

 7 #include<vector>

 8 #include<map>

 9 #include<set>

10 #define lson l,m,rt<<1

11 #define rson m+1,r,rt<<1|1

12 #define pbk push_back

13 #define mk make_pair

14 using namespace std;

15 const int N = 10000+10;

16 typedef pair<int,int> pii;

17 typedef long long LL;

18 set<pii> st;

19 set<pii> :: iterator it;

20 int n;

21 int main(){

22     while (~scanf("%d",&n),n) {

23         st.clear();

24         st.insert(mk(1000000000,1));

25         for (int i = 0; i < n; i++) {

26             int id,g;

27             scanf("%d%d",&id,&g);

28             pii t = mk(g,id);

29             st.insert(t);

30             it = st.lower_bound(t);

31             it++;

32             pii tmp1 = mk(0,-1), tmp2 = mk(0,-1);

33             if (it != st.end()) {

34                 tmp1 = *it;

35             }

36             it--;

37             if (it != st.begin()){

38                 tmp2 = *(--it);

39             }

40             int tp = -1,idx;

41             if (tmp1.second != -1) {

42                 if (tp == -1 || abs(tmp1.first - g) < tp){

43                     tp = abs(tmp1.first - g);

44                     idx =tmp1.second;

45                 }

46             }

47             if (tmp2.second != -1) {

48                 if (tp == -1 || abs(tmp2.first - g) <= tp) {

49                     tp = abs(tmp2.first - g);

50                     idx = tmp2.second;

51                 }

52             }

53             printf("%d %d\n",id,idx);

54         }

55     }

56 

57 

58     return 0;

59 }
View Code

 

你可能感兴趣的:(杭州邀请赛)