题目戳这里:51NOD算法马拉松8

某天晚上kpm在玩OSU!之余让我看一下B题...然后我就被坑进了51Nod...

A.还是01串

水题..怎么乱写应该都可以。记个前缀和然后枚举就行了.时间复杂度O(N)

#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; const int maxn = 1000009; char s[maxn];
int sum[maxn], N; int main() {
// freopen("test.in", "r", stdin); memset(sum, 0, sizeof sum); scanf("%s", s);
N = strlen(s);
sum[N] = 0;
for(int i = N; i--; )
sum[i] = sum[i + 1] + (s[i] == '1');
if(!sum[0]) {
puts("0"); return 0;
}
if(sum[0] == N) {
printf("%d\n", N); return 0;
}
for(int i = 1; i < N; i++) if(sum[0] - i == - sum[N]) {
printf("%d\n", i); return 0;
}
puts("-1"); return 0;
}

B.差和问题

题目大意:维护一个集合S,支持加入/删除元素v, 询问S里面的元素两两之差绝对值之和.N,Q≤100000.

拆掉绝对值, 每次我们加入或者删除x时,用平衡树维护x对答案的贡献即可,时间复杂度O(NlogN)

(PS.官方题解好像是离散化+树状数组..常数应该小一点..我一开始没加读入优化还被卡TLE了2个点..)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cctype>
#include<queue> using namespace std; typedef long long ll; const int maxn = 200009; int read() {
char c = getchar();
int ret = 0;
for(; !isdigit(c); c = getchar());
for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
return ret;
} struct Node { Node* ch[2];
ll sum;
int r, v, s; void upd() {
s = ch[0]->s + ch[1]->s + 1;
sum = ch[0]->sum + ch[1]->sum + v;
} } pool[maxn], *Null, *Root;
queue<Node*> q; Node* newNode(int v) {
Node* t = q.front(); q.pop();
t->s = 1;
t->v = v;
t->r = rand();
t->ch[0] = t->ch[1] = Null;
return t;
} void InitTreap() {
for(int i = 1; i < maxn; i++)
q.push(pool + i);
Root = Null = pool;
Null->sum = 0;
Null->s = 0;
Null->ch[0] = Null->ch[1] = Null;
} void Rotate(Node*&t, int d) {
Node* o = t->ch[d ^ 1];
t->ch[d ^ 1] = o->ch[d];
o->ch[d] = t;
t->upd(); o->upd();
t = o;
} void Insert(Node*&t, int v) {
// printf("%d\n", v);
if(t == Null) {
t = newNode(v);
} else {
int d = (v > t->v);
Insert(t->ch[d], v);
if(t->ch[d]->r > t->r)
Rotate(t, d ^ 1);
}
t->upd();
} void Delete(Node*&t, int v) {
int d = (t->v == v ? -1 : (v > t->v));
if(!~d) {
if(t->ch[0] != Null && t->ch[1] != Null) {
int _d = (t->ch[0]->r > t->ch[1]->r);
Rotate(t, _d);
Delete(t->ch[_d], v);
} else {
q.push(t);
t = (t->ch[0] == Null ? t->ch[1] : t->ch[0]);
}
} else
Delete(t->ch[d], v);
if(t != Null)
t->upd();
} ll ans = 0, sum = 0;
int sz = 0, N, Q; void update(int v, bool typ) {
int _sz = 0;
ll _sum = 0;
for(Node* t = Root; t != Null; ) {
if(t->v <= v)
_sz += t->ch[0]->s + 1, _sum += t->ch[0]->sum + t->v, t = t->ch[1];
else
t = t->ch[0];
} if(typ) {
// printf("%d %d %d %lld %lld\n", v, sz, _sz, sum, _sum);
ans += ll(v) * _sz - _sum;
ans += sum - _sum - ll(v) * (sz - _sz);
sz++, sum += v;
} else {
ans -= ll(_sz) * v - _sum;
ans -= sum - _sum - ll(v) * (sz - _sz);
sz--, sum -= v;
}
} bool Find(Node* t, int v) {
if(t == Null) return false;
if(t->v == v) return true;
return v < t->v ? Find(t->ch[0], v) : Find(t->ch[1], v);
} int main() {
// freopen("test.in", "r", stdin); InitTreap(); N = read(); Q = read();
for(int i = 0; i < N; i++) {
int v = read();
update(v, 1);
Insert(Root, v);
}
while(Q--) {
int opt = read();
if(opt == 3)
printf("%lld\n", ans);
else {
int v = read();
if(opt == 1) {
update(v, 1);
Insert(Root, v);
} else {
if(!Find(Root, v)) {
puts("-1"); continue;
}
update(v, 0);
Delete(Root, v);
}
}
} return 0;
}

C.找朋友

题目大意:给两个长度为N的数列A、B,一个有m个元素的集合K.Q个询问[l,r]内满足|Bi-Bj|∈K 的最大Ai+Aj.N,Q≤100000,M≤10

一开始不太会做...用莫队的话是O(M*N^1.5)..会TLE..因为至多有M*N对满足题意的数对,我们可以直接考虑他们对答案的贡献...那么离线将询问排序然后线段树维护就可以了,时间复杂度O(MNlogN)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype> using namespace std; const int maxn = 100009; int read() {
char c = getchar();
int ret = 0;
for(; !isdigit(c); c = getchar());
for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
return ret;
} int N, Q, M, A[maxn], B[maxn], _B[maxn], K[maxn], ans[maxn]; struct QUERY { int l, r, p; void Read(int x) {
l = read(); r = read(); p = x;
} bool operator < (const QUERY &o) const {
return l < o.l;
} } q[maxn]; void Init() {
memset(_B, -1, sizeof _B);
N = read(); Q = read(); M = read();
for(int i = 1; i <= N; i++) A[i] = read();
for(int i = 1; i <= N; i++) _B[B[i] = read()] = i;
for(int i = 0; i < M; i++) K[i] = read();
for(int i = 0; i < Q; i++) q[i].Read(i);
sort(q, q + Q);
// for(int i = 0; i < Q; i++)
// printf("[ %d , %d ] %d\n", q[i].l, q[i].r, q[i].p);
} int L, R, V; struct Node { Node *l, *r;
int v; Node() : v(0) {
l = r = NULL;
} void upd() {
if(l)
v = max(l->v, r->v);
} } pool[maxn << 1], *pt = pool, *Root; void Build(Node* t, int l, int r) {
if(l == r)
return;
int m = (l + r) >> 1;
Build(t->l = pt++, l, m);
Build(t->r = pt++, m + 1, r);
} void Modify(Node* t, int l, int r) {
if(l == r)
t->v = max(t->v, V);
else {
int m = (l + r) >> 1;
R <= m ? Modify(t->l, l, m) : Modify(t->r, m + 1, r);
t->upd();
}
} int Query(Node* t,int l, int r) {
if(L <= l && r <= R)
return t->v;
int m = (l + r) >> 1;
return max(L <= m ? Query(t->l, l, m) : 0, m < R ? Query(t->r, m + 1, r) : 0);
} int main() {
// freopen("test.in", "r", stdin);
// freopen("test.out", "w", stdout); Init(); Build(Root = pt++, 1, N); int p = Q - 1;
for(L = N; L; L--) {
// printf("%d\n", L);
int &v = B[L];
for(int j = 0; j < M; j++) {
if(v - K[j] >= 1 && ~_B[v - K[j]] && _B[v - K[j]] > L) {
V = A[L] + A[R = _B[v - K[j]]];
// printf("%d\n", V);
Modify(Root, 1, N);
}
if(v + K[j] <= N && ~_B[v + K[j]] && _B[v + K[j]] > L) {
V = A[L] + A[R = _B[v + K[j]]];
Modify(Root, 1, N);
}
}
// printf("%d\n", p);
while(~p && q[p].l == L) {
R = q[p].r;
// printf("p = %d %d \n", p, Query(Root, 1, N));
ans[q[p--].p] = Query(Root, 1, N);
}
// printf("%d\n", L);
if(p < 0) break;
} for(int i = 0; i < Q; i++)
printf("%d\n", ans[i]); return 0;
}

D,E,F都不会写...D题完全没什么思路.E题感觉可以搞但是因为要输出1~N的就不会了,O(N^2)妥妥的TLE啊...

F题推不出来...

这是E题..假如你会的话请评论...

膜11个AK..

51NOD 算法马拉松8的更多相关文章

  1. 51nod 算法马拉松 34 Problem D 区间求和2 (FFT加速卷积)

    题目链接  51nod 算法马拉松 34  Problem D 在这个题中$2$这个质数比较特殊,所以我们先特判$2$的情况,然后仅考虑大于等于$3$的奇数即可. 首先考虑任意一个点对$(i, j)$ ...

  2. 随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3

    先说说前面的SPOJ-RNG吧,题意就是给n个数,x1,x2,...,xn 每次可以生成[-x1,x1]范围的浮点数,把n次这种操作生成的数之和加起来,为s,求s在[A,B]内的概率 连续形的概率 假 ...

  3. 51Nod 算法马拉松21(迎新年)

    这次打算法马拉松是在星期五的晚上,发挥还算正常(废话,剩下的题都不会= =). 讲讲比赛经过吧. 8:00准时发题,拿到之后第一时间开始读. A配对,看上去像是二分图最大权匹配,一看范围吓傻了,先跳过 ...

  4. 51Nod 算法马拉松15 记一次悲壮而又开心的骗分比赛

    OwO 故事的起源大概是zcg前天发现51Nod晚上有场马拉松,然后他就很开心的过去打了 神奇的故事就开始了: 晚上的时候我当时貌似正在写线段树?然后看见zcg一脸激动告诉我第一题有九个点直接输出B就 ...

  5. 51Nod 算法马拉松23 开黑记

    惨啊……虽然开了半天黑,但是还是被dalao们踩了…… 第二次开黑,还是被卡在rank20了,我好菜啊……= = 写一写比赛经过吧…… 看到题之后习惯性都打开,A~D看上去似乎并没有什么思路,F应该是 ...

  6. 51Nod 算法马拉松22 开黑记

    这是一场惨烈的开黑大战,始于全机房开黑指望刷进rank前十拿钱的壮志,终于被各路神犇怒踩成rank20,差点200点头盾不保的落魄,想起将近一年前ad和zcg等学长挤进rank10的壮举,不由得唏嘘, ...

  7. 51nod算法马拉松 contest7

    A题 链接:http://www.51nod.com/contest/problem.html#!problemId=1417 推荐链接:http://blog.csdn.net/a837199685 ...

  8. 51nod算法马拉松15

    智力彻底没有了...看来再也拿不到奖金了QAQ... A B君的游戏 因为数据是9B1L,所以我们可以hash试一下数据... #include<cstdio> #include<c ...

  9. 51nod 算法马拉松18 B 非010串 矩阵快速幂

    非010串 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 如果一个01字符串满足不存在010这样的子串,那么称它为非010串. 求长度为n的非010串的个数.(对1e9+7取模) ...

随机推荐

  1. 一些User-Agent

    "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)", "Mozilla/4.0 (compatible; MSIE ...

  2. cf-A. Wet Shark and Odd and Even(水)

    A. Wet Shark and Odd and Even time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  3. android上下文

    在android中常常会遇到与context有关的内容 浅论一下context : 在语句 AlertDialog.Builder builder = new AlertDialog.Builder( ...

  4. 三维CAD塑造——基于所述基本数据结构一半欧拉操作模型

    三维CAD塑造--基于所述基本数据结构一半欧拉操作模型(elar, B_REP) (欧拉操作  三维CAD建模课程 三维CAD塑造 高曙明老师  渲染框架 brep 带洞 带柄 B_REP brep ...

  5. c# session总结

    C# 中对 Session 的“(string)”.“.ToString()”与“Convert.ToString”用法笔记 在实际操作当中,我们经常会遇到将 Session 的值转为 String ...

  6. iOS实践01

    去年放假之前大概完成了新浪微博项目,到现在也忘得差不多了,打算在重新写一遍.之前的一些笔记在新浪的博客SleenXiu,在这主要是把新浪微博以随笔的形式写在这,方便以后的复习. 先看看之前主要完成的几 ...

  7. *max_element函数和*min_element函数

    C++中*max_element(v.begin,v.end)找最大元素*min_element(v.begin,v.end)找最小元素. 数组: #include<iostream> # ...

  8. hdu3033I love sneakers! (分组背包,错了很多次)

    Problem Description After months of hard working, Iserlohn finally wins awesome amount of scholarshi ...

  9. codeforces 632C. The Smallest String Concatenation 排序

    题目链接 给出n个字符串, 将他们连在一起, 求连玩之后字典序最小的那种情况. 按a+b<b+a排序.... #include <iostream> #include <vec ...

  10. python使用mysql的三个模块:mysql.connector、sqlalchemy、MySQLdb

    在python中使用mysql其实很简单,只要先安装对应的模块即可,那么对应的模块都有什么?官方也没指定也没提供,pcat就推荐自己遇到的3个模块:mysql.connector.sqlalchemy ...