杭州邀请赛

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
",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
",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
", 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
",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
",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
",id,idx);
54         }
55     }
56 
57 
58     return 0;
59 }
View Code
原文地址:https://www.cnblogs.com/Rlemon/p/3250936.html