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 }
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 }
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 }
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 }
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 }
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 }
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 }