Codeforces 364

A

  第一题明显统计,注意0和long long(我WA,RE好几次)

/* 

 * Problem: A. Matrix

 * Author: Shun Yao

 */



#include <string.h>

#include <stdlib.h>

#include <limits.h>

#include <assert.h>

#include <stdio.h>

#include <ctype.h>

#include <math.h>

#include <time.h>



#include <map>

#include <set>

#include <list>

#include <stack>

#include <queue>

#include <deque>

#include <string>

#include <vector>

#include <bitset>

#include <utility>

#include <iomanip>

#include <numeric>

#include <sstream>

#include <iostream>

#include <algorithm>

#include <functional>



//using namespace std;



int a, n, b[4444], c[44444];

char s[4444];



int main(/*int argc, char **argv*/) {

    int i, j, x;

    long long ans;

    

    scanf("%d", &a);

    scanf(" %s", s + 1);

    n = strlen(s + 1);

    for (i = 1; i <= n; ++i)

        b[i] = s[i] - '0';

    memset(c, 0, sizeof c);

    ans = 0;

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

        x = 0;

        for (j = i; j <= n; ++j) {

            x += b[j];

            ++c[x];

        }

    }

    if (a) {

        for (i = 1; i <= 40000 && i * i <= a; ++i)

            if (a % i == 0 && a / i <= 40000)

                ans += static_cast<long long>(c[i]) * c[a / i] * (i * i == a ? 1 : 2);

    } else

        ans = static_cast<long long>(c[0]) * (n * (n + 1) - c[0]);

    printf("%I64d", ans);

    

    fclose(stdin);

    fclose(stdout);

    return 0;

}

B

  用背包算出每个价值是否出现过,然后贪心即可。

/* 

 * Problem: B. Free Market

 * Author: Shun Yao

 */



#include <string.h>

#include <stdlib.h>

#include <limits.h>

#include <assert.h>

#include <stdio.h>

#include <ctype.h>

#include <math.h>

#include <time.h>



#include <map>

#include <set>

#include <list>

#include <stack>

#include <queue>

#include <deque>

#include <string>

#include <vector>

#include <bitset>

#include <utility>

#include <iomanip>

#include <numeric>

#include <sstream>

#include <iostream>

#include <algorithm>

#include <functional>



//using namespace std;



int n, d, c[55], f[500010];



int main(/*int argc, char **argv*/) {

    int i, j, sum, ans1, ans2;

    

    scanf("%d%d", &n, &d);

    sum = 0;

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

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

        sum += c[i];

    }

    memset(f, 0, sizeof f);

    f[0] = 1;

    for (i = 1; i <= n; ++i)

        for (j = sum; j >= c[i]; --j)

            f[j] |= f[j - c[i]];

    ans1 = 0;

    ans2 = 0;

    while (ans1 < sum) {

        for (j = ans1 + d <= sum ? ans1 + d : sum; j > ans1; --j)

            if (f[j])

                break;

        if (j <= ans1)

            break;

        ans1 = j;

        ++ans2;

    }

    printf("%d %d", ans1, ans2);

    

    fclose(stdin);

    fclose(stdout);

    return 0;

}

C

  不懂证明,求解释。。。

D

  做法是随机算法(没有想到啊。)

/* 

 * Problem: D. Ghd

 * Author: Shun Yao

 */



#include <string.h>

#include <stdlib.h>

#include <limits.h>

#include <assert.h>

#include <stdio.h>

#include <ctype.h>

#include <math.h>

#include <time.h>



#include <map>

#include <set>

#include <list>

#include <stack>

#include <queue>

#include <deque>

#include <string>

#include <vector>

#include <bitset>

#include <utility>

#include <iomanip>

#include <numeric>

#include <sstream>

#include <iostream>

#include <algorithm>

#include <functional>



//using namespace std;



const int MAXN = 1000010;



int n;

long long a[MAXN], ans;

std::vector<long long> e, v;



long long gcd(long long a, long long b) {

	return !b ? a : gcd(b, a % b);

}



int main(/*int argc, char **argv*/) {

	int i, j, x;

	

//	freopen("D.in", "r", stdin);

//	freopen("D.out", "w", stdout);

	

	scanf("%d", &n);

	for (i = 1; i <= n; ++i)

		scanf("%I64d", a + i);

	srand((unsigned)time(0));

	ans = 0;

	while (clock() < 3000L) {

		x = static_cast<long long>(rand()) * rand() % n + 1;

		e.clear();

		v.clear();

		for (i = 1; static_cast<long long>(i) * i <= a[x]; ++i)

			if (a[x] % i == 0) {

				e.push_back(i);

				if (static_cast<long long>(i) * i != a[x])

					e.push_back(a[x] / i);

			}

		std::sort(e.begin(), e.end());

		v.resize(e.size(), 0);

		for (i = 1; i <= n; ++i)

			++v[std::lower_bound(e.begin(), e.end(), gcd(a[x], a[i])) - e.begin()];

		for (i = 0; i < static_cast<int>(e.size()); ++i) {

			for (j = i + 1; j < static_cast<int>(e.size()); ++j)

				if (e[j] % e[i] == 0)

					v[i] += v[j];

			if (v[i] + v[i] >= n)

				ans = std::max(ans, e[i]);

		}

	}

	printf("%I64d", ans);

	

	fclose(stdin);

	fclose(stdout);

	return 0;

}

 E

  二维分治。

/*

 * Problem: E. Empty Rectangles

 * Author: Shun Yao

 */



#include <string.h>

#include <stdlib.h>

#include <limits.h>

#include <assert.h>

#include <stdio.h>

#include <ctype.h>

#include <math.h>

#include <time.h>



#include <map>

#include <set>

#include <list>

#include <stack>

#include <queue>

#include <deque>

#include <string>

#include <vector>

#include <bitset>

#include <utility>

#include <iomanip>

#include <numeric>

#include <sstream>

#include <iostream>

#include <algorithm>

#include <functional>



//using namespace std;



int n, m, k;

char s[2505][2505];

long long a[2505][2505];



inline long long sum(int r1, int c1, int r2, int c2) {

	return a[r2][c2] - a[r1 - 1][c2] - a[r2][c1 - 1] + a[r1 - 1][c1 - 1];

}



long long go(int r1, int c1, int r2, int c2) {

	if (r1 == r2 && c1 == c2)

		return sum(r1, c1, r2, c2) == k;

	if (r2 - r1 > c2 - c1) {

		long long cnt = 0;

		int m = (r1 + r2) >> 1;

		int up[k + 1], dw[k + 1];

		for (int i = c1; i <= c2; i++) {

			for (int x = 0; x <= k; x++)up[x] = m - r1 + 1, dw[x] = r2 - m;

			for (int j = i; j <= c2; j++) {

				for (int x = 0; x <= k; x++) {

					while (up[x] && sum(m - up[x] + 1, i, m, j) > x)

						--up[x];

					while (dw[x] && sum(m + 1, i, m + dw[x], j) > x)

						--dw[x];

				}

				for (int x = 0; x <= k; x++) {

					cnt += (long long)(up[x] - (x ? up[x - 1] : 0)) * (dw[k - x] - (k - x ? dw[k - x - 1] : 0));

				}

			}

		}

		return cnt + go(r1, c1, m, c2) + go(m + 1, c1, r2, c2);

	} else {

		long long cnt = 0;

		int m = (c1 + c2) >> 1;

		int up[k + 1], dw[k + 1];

		for (int i = r1; i <= r2; i++) {

			for (int x = 0; x <= k; x++)up[x] = m - c1 + 1, dw[x] = c2 - m;

			for (int j = i; j <= r2; j++) {

				for (int x = 0; x <= k; x++) {

					while (up[x] && sum(i, m - up[x] + 1, j, m) > x)up[x]--;

					while (dw[x] && sum(i, m + 1, j, m + dw[x]) > x)dw[x]--;

				}

				for (int x = 0; x <= k; x++) {

					cnt += (long long)(up[x] - (x ? up[x - 1] : 0)) * (dw[k - x] - (k - x ? dw[k - x - 1] : 0));

				}

			}

		}

		return cnt + go(r1, c1, r2, m) + go(r1, m + 1, r2, c2);

	}

}



int main() {

	freopen("E.in", "r", stdin);

	freopen("E.out", "w", stdout);

	

	scanf("%d%d%d", &n, &m, &k);

	for (int i = 1; i <= n; i++)scanf("%s", &s[i][1]);

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

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

			a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + s[i][j] - '0';

		}

	}

	printf("%I64d", go(1, 1, n, m));

	

	fclose(stdin);

	fclose(stdout);

	return 0;

}

 

你可能感兴趣的:(codeforces)