[BZOJ2683][BZOJ4066]简单题

试题描述

你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:

命令

参数限制

内容

1 x y A

1<=x,y<=N,A是正整数

将格子x,y里的数字加上A

2 x1 y1 x2 y2

1<=x1<= x2<=N

1<=y1<= y2<=N

输出x1 y1 x2 y2这个矩形内的数字和

3

终止程序

输入

输入文件第一行一个正整数N。
接下来每行一个操作。每条命令除第一个数字之外,
均要异或上一次输出的答案last_ans,初始时last_ans=0。(BZOJ2683不需要强制在线)

输出

对于每个2操作,输出一个对应的答案。

输入示例(BZOJ2683)


输出示例(BZOJ2683)


输入示例(BZOJ4066)


输出示例(BZOJ4066)


数据规模及约定

1<=N<=500000,操作数不超过200000个,内存限制20M,保证答案在int范围内并且解码之后数据仍合法。

题解

只有权限号可以享受的双倍经验题(雾)。

2683这道数据水,最裸的kd树就卡时限过了。。。

4066这题数据强,需要加一个定期重构,就是加入的元素达到了某一些固定值就暴力把整棵kd树重新构造一遍,这样就不会被卡成“n2 的优秀算法了”。

2683(不强制在线无定期重构慢的要死):

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std; const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
} #define maxn 200010
#define oo 2147483647
int root, ToT, lc[maxn], rc[maxn];
struct Node {
int x[2], mx[2], mn[2], val, sum;
bool operator == (const Node& t) const { return x[0] == t.x[0] && x[1] == t.x[1]; }
} nodes[maxn]; Node x, y;
void maintain(int o) {
int l = lc[o], r = rc[o];
for(int i = 0; i < 2; i++) {
nodes[o].mx[i] = max(max(nodes[l].mx[i], nodes[r].mx[i]), nodes[o].x[i]);
nodes[o].mn[i] = min(min(nodes[l].mn[i], nodes[r].mn[i]), nodes[o].x[i]);
}
nodes[o].sum = nodes[l].sum + nodes[r].sum + nodes[o].val;
// printf("maintain(%d): %d %d %d %d %d\n", o, nodes[o].sum, nodes[o].mx[0], nodes[o].mn[0], nodes[o].mx[1], nodes[o].mn[1]);
return ;
}
void add(int& o, bool cur) {
if(!o){ nodes[o = ++ToT] = x; return maintain(o); }
if(nodes[o] == x){ nodes[o].val += x.val; nodes[o].sum += x.val; return maintain(o); }
add(x.x[cur] < nodes[o].x[cur] ? lc[o] : rc[o], cur ^ 1);
return maintain(o);
}
bool all(int o) { return x.x[0] <= nodes[o].mn[0] && nodes[o].mx[0] <= y.x[0] && x.x[1] <= nodes[o].mn[1] && nodes[o].mx[1] <= y.x[1]; }
bool has(int o) { return !(nodes[o].mx[0] < x.x[0] || nodes[o].mn[0] > y.x[0] || nodes[o].mx[1] < x.x[1] || nodes[o].mn[1] > y.x[1]); }
int query(int o) {
if(!o) return 0;
int ans = 0;
if(all(lc[o])) ans += nodes[lc[o]].sum;
else if(has(lc[o])) ans += query(lc[o]);
if(all(rc[o])) ans += nodes[rc[o]].sum;
else if(has(rc[o])) ans += query(rc[o]);
int nx = nodes[o].x[0], ny = nodes[o].x[1];
if(x.x[0] <= nx && nx <= y.x[0] && x.x[1] <= ny && ny <= y.x[1]) ans += nodes[o].val;
return ans;
} int main() {
nodes[0].mx[0] = nodes[0].mx[1] = -oo;
nodes[0].mn[0] = nodes[0].mn[1] = oo;
nodes[0].val = nodes[0].sum = 0;
int n = read();
n = read();
while(n < 3) {
if(n == 1) {
x.x[0] = read(); x.x[1] = read(); x.val = read();
add(root, 1);
}
if(n == 2) {
x.x[0] = read(); x.x[1] = read(); y.x[0] = read(); y.x[1] = read();
printf("%d\n", query(root));
}
n = read();
} return 0;
}

4066(强制在线加定期重构但还是很慢= =):

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std; const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
} #define maxn 200010
#define oo 2147483647
int root, ToT, lc[maxn], rc[maxn];
bool Cur;
struct Node {
int x[2], mx[2], mn[2], val, sum;
bool operator == (const Node& t) const { return x[0] == t.x[0] && x[1] == t.x[1]; }
bool operator < (const Node& t) const { return x[Cur] < t.x[Cur]; }
} nodes[maxn]; Node x, y;
void maintain(int o) {
int l = lc[o], r = rc[o];
for(int i = 0; i < 2; i++) {
nodes[o].mx[i] = max(max(nodes[l].mx[i], nodes[r].mx[i]), nodes[o].x[i]);
nodes[o].mn[i] = min(min(nodes[l].mn[i], nodes[r].mn[i]), nodes[o].x[i]);
}
nodes[o].sum = nodes[l].sum + nodes[r].sum + nodes[o].val;
// printf("maintain(%d): %d %d %d %d %d\n", o, nodes[o].sum, nodes[o].mx[0], nodes[o].mn[0], nodes[o].mx[1], nodes[o].mn[1]);
return ;
}
void add(int& o, bool cur) {
if(!o){ nodes[o = ++ToT] = x; return maintain(o); }
if(nodes[o] == x){ nodes[o].val += x.val; nodes[o].sum += x.val; return maintain(o); }
add(x.x[cur] < nodes[o].x[cur] ? lc[o] : rc[o], cur ^ 1);
return maintain(o);
}
void build(int& o, int L, int R, int cur) {
if(L > R){ o = 0; return ; }
int M = L + R >> 1; o = M;
Cur = cur; nth_element(nodes + L, nodes + M, nodes + R + 1);
build(lc[o], L, M - 1, cur ^ 1); build(rc[o], M + 1, R, cur ^ 1);
return maintain(o);
}
bool all(int o) { return x.x[0] <= nodes[o].mn[0] && nodes[o].mx[0] <= y.x[0] && x.x[1] <= nodes[o].mn[1] && nodes[o].mx[1] <= y.x[1]; }
bool has(int o) { return !(nodes[o].mx[0] < x.x[0] || nodes[o].mn[0] > y.x[0] || nodes[o].mx[1] < x.x[1] || nodes[o].mn[1] > y.x[1]); }
int query(int o) {
if(!o) return 0;
int ans = 0;
if(all(lc[o])) ans += nodes[lc[o]].sum;
else if(has(lc[o])) ans += query(lc[o]);
if(all(rc[o])) ans += nodes[rc[o]].sum;
else if(has(rc[o])) ans += query(rc[o]);
int nx = nodes[o].x[0], ny = nodes[o].x[1];
if(x.x[0] <= nx && nx <= y.x[0] && x.x[1] <= ny && ny <= y.x[1]) ans += nodes[o].val;
return ans;
} int main() {
nodes[0].mx[0] = nodes[0].mx[1] = -oo;
nodes[0].mn[0] = nodes[0].mn[1] = oo;
nodes[0].val = nodes[0].sum = 0;
int n = read(), lastans = 0;
n = read();
while(n < 3) {
if(n == 1) {
x.x[0] = read() ^ lastans; x.x[1] = read() ^ lastans; x.val = read() ^ lastans;
add(root, 1);
if(ToT % 1000 == 0) build(root, 1, ToT, 1);
}
if(n == 2) {
x.x[0] = read() ^ lastans; x.x[1] = read() ^ lastans; y.x[0] = read() ^ lastans; y.x[1] = read() ^ lastans;
printf("%d\n", lastans = query(root));
}
n = read();
} return 0;
}

其实这道题我第一眼看上去是树套树删边题,结果一看内存限制20M。。。还好没写树套树= =

[BZOJ2683][BZOJ4066]简单题的更多相关文章

  1. 【BZOJ1176】[Balkan2007]Mokia/【BZOJ2683】简单题 cdq分治

    [BZOJ1176][Balkan2007]Mokia Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=1600 ...

  2. bzoj4066: 简单题 K-Dtree

    bzoj4066: 简单题 链接 bzoj 思路 强制在线.k-dtree. 卡常啊.空间开1e6就T了. 代码 #include <bits/stdc++.h> #define my_m ...

  3. Bzoj4066 简单题

    Time Limit: 50 Sec  Memory Limit: 20 MBSubmit: 2185  Solved: 581 Description 你有一个N*N的棋盘,每个格子内有一个整数,初 ...

  4. 【BZOJ2683】简单题 [分治][树状数组]

    简单题 Time Limit: 50 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 你有一个N*N的棋盘,每个格子内有一 ...

  5. BZOJ4066 简单题(KD-Tree)

    板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  6. 【bzoj1176】[Balkan2007]Mokia/【bzoj2683】简单题 CDQ分治+树状数组

    bzoj1176 题目描述 维护一个W*W的矩阵,初始值均为S(题目描述有误,这里的S没有任何作用!).每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数 ...

  7. 【BZOJ2683】简单题

    cdq分治妙啊 (被改过题面的)原题: dydxh所出的题目是这样的:有一个N*N矩阵,给出一系列的修改和询问,修改是这样的:将(x,y)中的数字加上k,而询问是这样的:求(x1,y1)到(x2,y2 ...

  8. 【kd-tree】bzoj4066 简单题

    同p1176. #include<cstdio> #include<cmath> #include<algorithm> using namespace std; ...

  9. BZOJ4066:简单题(K-D Tree)

    Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:   命令 参数限制 内容 1 x y A 1<=x,y<=N,A是正整数 ...

随机推荐

  1. maven integration with eclipse 3.0.4 does not work with NTLM proxy

    Recently downloaded m2e(maven integration with eclipse). The version is 3.0.4. My environment is beh ...

  2. jquery的常用的容易忘记的东西

    1.浅谈jQuery中 wrap() wrapAll() 与 wrapInner()的差异  http://www.jb51.net/article/57336.htm 2. jquery的each方 ...

  3. css的垂直居中

    请先看博客:http://www.jb51.net/css/39629.html

  4. 9、面向对象以及winform的简单运用(输入输出流、图像的上传和读取)

    一.输入输出流 1.概念: 输入输出流主要用于保存.读取文件,其内容保存在内存中. 2.使用方法: using System.IO; //System.IO 命名空间包含允许读写文件和数据流的类型以及 ...

  5. OC基础--成员变量的封装

    一.封装的作用: 1.重用 2.不必关心具体的实现 3.面向对象三大特征之一 4.具有安全性 二.OC中成员变量的命名规范以及注意事项 1.命名规范--.成员变量都以下划线“_”开头 1)为了跟get ...

  6. nslog

    今天有人问我怎么更好的使用nslog,打包的时候老注释 pch里加下面的代码就好了平时debug的时候打印,release后就不打印了 #ifdef DEBUG#define NSLog(...) N ...

  7. Pro Git 读书笔记

    一. 起步 1. 集中式版本控制缺点:中央服务器的单点故障. 分布式版本控制优点:客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来. 这么一来,任何一处协同工作用的服务器发生故障,事后 ...

  8. Java异常-一般异常和运行时异常的区别

    Java提供了两类主要的异常:runtime exception和checked exception.checked 异常也就是我们经常遇到的IO异常,以及SQL异常都是这种异常.对于这种异常, JA ...

  9. 用requests库实现登录遇到的问题

    想登录zhihu,然后总是得到403 foribidden的错误,各种谷歌百度,得到结论说是输入错误或者是url错误,用fldder发现的确是url错了,post的地址是错误的 ==. 开始以为是#s ...

  10. android anr分析方法

    目录(?)[+] 案例1关键词ContentResolver in AsyncTask onPostExecute high iowait 案例2关键词在UI线程进行网络数据的读写   一:什么是AN ...