NOIP2013 재생
D1T1 P1965 돌고 게임
물어에 \ (X + m \ 시간 10 ^ K \) 막 \ (\ N-) 의 값.
KSM 템플릿입니다.
D1T2 P1966은 일치하는 줄
\ (\ SUM (a_ib_i) = A_I ^ 2 ^ 2 + b_i ^ 2-2a_ib_i \) , 상관 제곱 용어 행이 증가 될 필요가없는 방법이다 (a_ib_i \) \ 이.
그것은 재 배열 불평등으로 알려져 있습니다 : 가까이 두 숫자, 더 큰 값.
그래서해야 \ (A \) 배열과 \의 (b \) 이 가장 큰이며, 해당 다음, 배열은 분류되어 있습니다.
이제 문제는 방법이다 \ (A \) 그림의 크기 관계가된다 \ (b \) ?
구체적인 수치는 크기에 영향을 미치는, 그래서 우리 모두 이산 때문입니다.
확인 \ (c를 [A [내가] = (B)는 [I]는 \) , 가장 대답하자 경우 \ (c [A [I] = A [i]는 \) 이다 \ (c [i]를 I = \) .
그것은된다 (C \) \ 어레이로부터해진다 \ (1 \) 받는 \ N- (\) 배열의 최소 동작.
맞아 반전되지 않는 이유는 무엇입니까? 펜윅 트리 나는 일종의 쓰기 시작 병합.
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 100005, mod = 99999997;
int a[maxn], b[maxn], c[maxn], d[maxn], q[maxn], t[maxn], ans;
int n;
bool cmp1(int x, int y)
{
return a[x] < a[y];
}
bool cmp2(int x, int y)
{
return b[x] < b[y];
}
int read()
{
int ans = 0, s = 1;
char ch = getchar();
while(ch > '9' || ch < '0')
{
if(ch == '-') s = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
ans = ans * 10 + ch - '0';
ch = getchar();
}
return s * ans;
}
void msort(int l, int r)
{
int mid = (l + r) >> 1;
if(l != r) msort(l, mid), msort(mid + 1, r);
int i = l, j = mid + 1, k = l;
while(i <= mid && j <= r)
{
if(q[i] > q[j])
{
ans = (ans + j - k) % mod;
t[k++] = q[j++];
}
else t[k++] = q[i++];
}
while(i <= mid) t[k++] = q[i++];
while(j <= r) t[k++] = q[j++];
for(int i = l; i <= r; i++) q[i] = t[i];
}
int main()
{
n = read();
for(int i = 1; i <= n; i++)
{
a[i] = read();
c[i] = i;
}
for(int i = 1; i <= n; i++)
{
b[i] = read();
d[i] = i;
}
sort(c + 1, c + 1 + n, cmp1);
sort(d + 1, d + 1 + n, cmp2);
for(int i = 1; i <= n; i++) q[c[i]] = d[i];
msort(1, n);
printf("%d\n", ans);
return 0;
}
D1T3 P1967의 트럭
이 그래프 최대 스패닝 트리의 측면 될 것입니다 각면을 통해 (추측) 증명, 또는 당신은 잃게됩니다 어렵지 않다.
그래서, 최대 스패닝 트리를주고이를 변경 크루스 칼 관행을 기호를 사용합니다.
다음에, 기본적인 최소 경로 트리되고, 트리를 이용하여 단면 세그먼트 트리가 유지 될 수있다.
이 질문은 또한 폭력 점프 LCA 아를 끌 수 있습니다. . .
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 10005, maxm = 50005, INF = 19260817;
int n, m, q;
//kruskal
struct edge
{
int u, v, w;
} ee[maxm];
int f[maxn];
//new graph
struct Edge
{
int next, to, weight;
} e[maxm << 1];
int head[maxn], etot;
//shupou
int dep[maxn], size[maxn], wson[maxn], fa[maxn];
int top[maxn], dfn[maxn], pre[maxn], dtot;
int path[maxn];
//functions
int read()
{
int ans = 0, s = 1;
char ch = getchar();
while(ch > '9' || ch < '0')
{
if(ch == '-') s = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
ans = ans * 10 + ch - '0';
ch = getchar();
}
return s * ans;
}
int find(int x)
{
if(f[x] == x) return x;
return f[x] = find(f[x]);
}
bool cmp(const edge x, const edge y)
{
return x.w > y.w;
}
void link(int u, int v, int w)
{
e[++etot] = (Edge){head[u], v, w};
head[u] = etot;
}
void kruskal()
{
for(int i = 1; i <= n; i++) f[i] = i;
sort(ee + 1, ee + m + 1, cmp);
for(int i = 1; i <= m; i++)
{
int x = find(ee[i].u), y = find(ee[i].v), w = ee[i].w;
if(x != y)
{
link(x, y, w); link(y, x, w);
f[x] = y;
}
}
}
void dfs1(int u, int ff, int w)
{
size[u] = 1; fa[u] = ff; dep[u] = dep[ff] + 1; path[u] = w;
for(int i = head[u]; i; i = e[i].next)
{
int v = e[i].to;
if(v == ff) continue;
dfs1(v, u, e[i].weight);
size[u] += size[v];
if(size[v] > size[wson[u]]) wson[u] = v;
}
}
void dfs2(int u, int topf)
{
dfn[u] = ++dtot; pre[dtot] = u; top[u] = topf;
if(wson[u]) dfs2(wson[u], topf);
for(int i = head[u]; i; i = e[i].next)
{
int v = e[i].to;
if(v == fa[u] || v == wson[u]) continue;
dfs2(v, v);
}
}
int getlca(int u, int v)
{
if(find(u) != find(v)) return -1;
while(top[u] != top[v])
{
if(dep[top[u]] < dep[top[v]]) swap(u, v);
u = fa[top[u]];
}
if(dep[u] > dep[v]) swap(u, v);
return u;
}
int getans(int u, int v, int lca)
{
if(lca == -1) return -1;
int ans = INF;
while(u != lca)
{
ans = min(ans, path[u]);
u = fa[u];
}
while(v != lca)
{
ans = min(ans, path[v]);
v = fa[v];
}
return ans;
}
int main()
{
n = read(), m = read();
for(int i = 1; i <= m; i++)
{
ee[i] = (edge){read(), read(), read()};
}
kruskal();
for(int i = 1; i <= n; i++)
{
if(dep[i] == 0)
{
dfs1(i, 0, 0); dfs2(i, i);
}
}
q = read();
while(q--)
{
int x = read(), y = read();
printf("%d\n", getans(x, y, getlca(x, y)));
}
return 0;
}
D2T1 P1969 빌딩 대회
NOIP2018 원래 제목을 기념하지만, 불행히도 나는하지 않았다
분할 정복 방법은 카드가 될 수있다 \ (O합니다 () ^ 2 N- \) , 포지티브 용액 실제로 \ (O (N) \) 재발.
세트 \는 (ANS는 [I]는 \) 전방에있다 \ (I는 \) 않음 번째 각 순회 얻어진다 \ (I는 \) 두 가지 경우 :
- \ (A [I]가 \ 당량 A가 [-I. 1] \) 의 팽창 영역의 전면에 추가 만 방법을 필요로하지 않는다. 즉,이 대답의 앞에 상속됩니다.
- \ (A [I]> = A [I-. (1)] \) , 다음 추가로 필요 \을 (A [i]를 -a [ I-1] \) 이 일 작성 작업.
완성 된 2 예 작성 작업이 계산되어 있기 때문에 이러한 행위는 설립되었습니다.
D2T2 P1970 정원사
이 질문은 하나의 DP이고, 하나는 욕심 형이상학, 두 개의 솔루션을 제공합니다.
방법은 DP를 구비 \을 (최대 [I] \) 와 \ (아래 [I] \) 의 기록 전에 \ (I \) 번째 현재 최대 시퀀스 길이하여 상승 또는 하강된다.
당신이 증가 얻을 경우, 같은 이유로 감소, n은 플러스 1 방울의 최대 길이에서 꺼낸다.
업데이트하지 않으면 동시에, 이전의 최대 길이는 상속 될 수 있습니다.
코드 청 치 :
#include<cstdio>
using namespace std;
const int maxn = 100005;
inline int max(int a, int b)
{
if(a > b) return a;
return b;
}
int a[maxn], up[maxn], down[maxn];
int n;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
up[1] = down[1] = 1;
for(int i = 2; i <= n; i++)
{
if(a[i - 1] < a[i]) up[i] = down[i - 1] + 1;
else up[i] = up[i - 1];
if(a[i - 1] > a[i]) down[i] = up[i - 1] + 1;
else down[i] = down[i - 1];
}
printf("%d\n", max(up[n], down[n]));
return 0;
}
형이상학 욕심 접근 방식은 이것이다 :
#include<bits/stdc++.h>
using namespace std;
int n,h[1000005],ans=1;bool con;
int main()
{
cin>>n;for(int i=1;i<=n;i++) cin>>h[i];
if(h[2]>=h[1]) con=1;
for(int i=1;i<=n;i++)
{
if(con==0&&i==n) {ans++;break;}
if(con==1) if(h[i+1]<h[i]){ans++;con=0;continue;}
if(con==0) if(h[i+1]>h[i]) {ans++;con=1;continue;}
}
cout<<ans;
}
제 1 및 제 2 결정 방향을 결정을 통해, 그 후 일정하게 증가하거나 마지막을 감소 분명히 응답은 최적이다.
그 단계 ANS는 ++ 정말 좋지 않다.
이 코드는 데이터 카드의 복수를 반복 할 수 있지만,이 질문에 데이터를 균일 난수를 배포됩니다.
D2T3 P1979 화용
https://www.luogu.org/blog/moisture2333/solution-p1979w
#include<bits/stdc++.h>
const int maxn = 31;
const int INF = 0x3f3f3f3f;
const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, -1, 1};
int n, m, Q;
int ex, ey, bx, by, cx, cy;
int G[maxn][maxn];
bool vis[maxn][maxn];
bool ok[maxn][maxn][4];
struct Edges {
int next, to, weight;
} e[200005];
int head[10005], tot;
bool visit[10005];
int dist[10005];
void link(int u, int v, int w) {
e[++tot] = (Edges){head[u], v, w};
head[u] = tot;
}
int getid(int x, int y, int dir) {
return 4 * ((x - 1) * m + y) - 4 + dir;
}
int query(int x, int y) {
if(x < 1 || x > n || y < 1 || y > m) return 0;
return G[x][y];
}
int bfs(int nx, int ny, int sx, int sy, int tx, int ty) {
// ¿Õ°×¸ñ×ÓÂÒת ¶øÄ¿±êÆå×Ó²»Òƶ¯
struct Nodes {
int x, y, dis;
};
std::queue<Nodes> q;
memset(vis, false, sizeof vis);
q.push((Nodes){sx, sy, 0}); vis[sx][sy] = true;
while(!q.empty()) {
Nodes sb = q.front(); q.pop();
if(sb.x == tx && sb.y == ty) return sb.dis;
for(int i = 0; i < 4; i++) {
int newx = sb.x + dx[i], newy = sb.y + dy[i];
if(query(newx, newy)) {
if(vis[newx][newy]) continue;
if(newx == nx && newy == ny) continue;
q.push((Nodes){newx, newy, sb.dis + 1}); vis[newx][newy] = true;
}
}
}
return INF;
}
void init() {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(!G[i][j]) continue;
for(int k = 0; k < 4; k++) {
if(query(i + dx[k], j + dy[k])) ok[i][j][k] = true;
}
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
for(int k = 0; k < 4; k++) {
for(int l = k + 1; l < 4; l++) {
if(ok[i][j][k] && ok[i][j][l]) {
int a = getid(i, j, k), b = getid(i, j, l);
int temp = bfs(i, j, i + dx[k], j + dy[k], i + dx[l], j + dy[l]);
if(temp == INF) continue;
link(a, b, temp); link(b, a, temp);
}
}
}
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j < m; j++) {
if(ok[i][j][3] && ok[i][j + 1][2]) {
int a = getid(i, j, 3), b = getid(i, j + 1, 2);
link(a, b, 1); link(b, a, 1);
}
}
}
for(int i = 1; i < n; i++) {
for(int j = 1; j <= m; j++) {
if(ok[i][j][1] && ok[i + 1][j][0]) {
int a = getid(i, j, 1), b = getid(i + 1, j, 0);
link(a, b, 1); link(b, a, 1);
}
}
}
}
void solve() {
std::queue<int> q;
memset(dist, 0x3f, sizeof dist);
for(int i = 0; i < 4; i++) {
int newx = bx + dx[i], newy = by + dy[i];
if(query(newx, newy)) {
int temp = bfs(bx, by, ex, ey, newx, newy);
if(temp == INF) continue;
int idx = getid(bx, by, i);
dist[idx] = temp;
q.push(idx); visit[idx] = true;
}
}
while(!q.empty()) {
int u = q.front(); q.pop(); visit[u] = false;
for(int i = head[u]; i; i = e[i].next) {
int v = e[i].to;
if(dist[v] > dist[u] + e[i].weight) {
dist[v] = dist[u] + e[i].weight;
if(!visit[v]) {
q.push(v); visit[v] = true;
}
}
}
}
int ans = INF;
for(int i = 0; i < 4; i++) {
int temp = getid(cx, cy, i);
ans = std::min(ans, dist[temp]);
}
if(ans == INF) printf("-1\n");
else printf("%d\n", ans);
}
int main() {
scanf("%d %d %d", &n, &m, &Q);
for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d", &G[i][j]);
init();
while(Q--) {
scanf("%d %d %d %d %d %d", &ex, &ey, &bx, &by, &cx, &cy);
if(bx == cx && by == cy) {
printf("0\n");
} else if(!G[cx][cy] || !G[bx][by]) {
printf("-1\n");
} else solve();
}
return 0;
}