I 签到c语言题
K 裸最小生成树 不小心wa了一发
H 任意两点最短路的最长路 map+spfa水过...讲道理算复杂度是常数很大的O(ne) 加上map 还以为会tle
J 看好题意 暴力状态压缩枚举就好
B 计算几何 枚举角度计算点到矩形距离
C看了半天觉得不可做..没怎么往dp想... 正解是动态规划(或者说递推)...有点难
D 二维树状数组+坐标旋转+离散化(或者线段树套树 不用坐标旋转) ..(现场赛时不卡内存 不用离散化)线下比线上难得多系列
F 计算几何 相当于判断点是否在多边形内 不是太难 现场可能是精度要求太高导致个位数ac率..(完全精度?)
A 复杂数据结构之伸展树..据说略模板
E G 2个防ak题...
简单题还比较顺利..还可以再快点...
中等题bcdf可做 计算几何比较占电脑 需要良好的模板和熟练度... dp看智力 几乎不占键盘时间 感觉不可做的中等题往dp想好了..
中期有不太难的计算几何可以上机搞
现场赛不限内存 据说d题半G的数组ac了 只优化内存的离散化几乎不用写...
树状数组有必要学习一个..
应该备良好的图论及计算几何模板..
C动态规划代码:
#include<cstdio>
#include<cstring>
int c[1000005], sum[1000005], num[1000005], pre[1000005], a[1000005];
long long dp[1000005];//dp值是O(n^2)级 会超int
int main()
{
int i, x, n, m;
while (scanf("%d", &n) && n)
{
for (i = 1; i <= n; i++) scanf("%d", &a[i]);
memset(pre, 0, sizeof(pre)), memset(c, 0, sizeof(c));
for (i = 1; i <= n; i++)//c[i] 间距为i的相同数的对数 第一次出现则记录数组下标
c[i - pre[a[i]]]++, pre[a[i]] = i;
sum[n] = c[n];
for (i = n - 1; i>0; i--)//sum[i] 间距大于等于i的相同数的对数
sum[i] = sum[i + 1] + c[i];
memset(c, 0, sizeof(c));
c[a[n]] = 1, num[1] = 1;
for (i = 2; i <= n; i++)//num[i] 后i个数中不同数的个数
if (!c[a[n - i + 1]])//c[i] 数i是否出现过 相当于vis
num[i] = num[i - 1] + 1, c[a[n - i + 1]] = 1;
else
num[i] = num[i - 1];
dp[1] = n;
for (i = 2; i <= n; i++)//dp[i]相当于dp[i-1]去掉最后1组 再在之前每组后面加1个元素
//所以 减去后i-1个不同数次数 后面加的数里 只要前一次出现相同元素不小于i 就+1
dp[i] = dp[i - 1] - num[i - 1] + sum[i];//总复杂度是常数很大的O(N)
scanf("%d", &m);
while (m--&&scanf("%d", &x))
printf("%lld\n", dp[x]);
}
}
D 二维树状数组(模板)+坐标旋转+离散化:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mm 80005
int n, m, w, e, h[mm << 5], ss[mm << 5], pp[mm], xx[mm], yy[mm], zz[mm];
void ha(int x, int y)//离散化
{//对与每个位运算涉及的点都要离散化
for (int i = x; i <= w; i += i&-i)
for (int j = y; j <= w; j += j&-j)
h[e++] = i * w + j;//转化至一维
}
void add(int x, int y, int d)
{
for (int i = x; i <= w; i += i&-i)
for (int j = y; j <= w; j += j&-j)
ss[lower_bound(h + 1, h + e, i*w + j) - h] += d;
}
int sum(int x, int y)
{
int s = 0;
for (int i = x; i; i -= i&-i)
for (int j = y; j; j -= j&-j)
{
int pos = lower_bound(h + 1, h + e, i*w + j) - h;
if (h[pos] == i * w + j)
s += ss[pos];
}
return s;
}
int main()
{
int a, b, c, d, x, y;
while (scanf("%d", &n) && n)
{
e = 1, w = n << 1;
scanf("%d", &m);
memset(ss, 0, sizeof(ss));
for (int i = 1; i <= m; i++)
{
scanf("%d%d%d%d", pp + i, xx + i, yy + i, zz + i);
x = xx[i] - yy[i] + n, y = xx[i] + yy[i];
if (pp[i] == 1) ha(x, y);
}
sort(h + 1, h + e), e = unique(h + 1, h + e) - h;
for (int i = 1; i <= m; i++)
{
x = xx[i] - yy[i] + n, y = xx[i] + yy[i];
if (pp[i] == 1) add(x, y, zz[i]);
else {
a = max(1, x - zz[i]), b = max(1, y - zz[i]);
c = min(w, x + zz[i]), d = min(w, y + zz[i]);
printf("%d\n", sum(c, d) - sum(c, b - 1) - sum(a - 1, d) + sum(a - 1, b - 1));
}
}
}
}
离散化的地方很妙..