[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. 【niubi-job——一个分布式的任务调度框架】----安装教程

    niubi-job是什么 niubi-job是LZ耗时三个星期,费尽心血打造的一个具备高可靠性以及水平扩展能力的分布式任务调度框架,采用quartz作为底层的任务调度管理器,zookeeper做集群的 ...

  2. java之Cookie详解

    Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是 ...

  3. [BZOJ 1085][SCOI2005]骑士精神(IDA*)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1085 分析: 首先第一感觉是宽搜,但是空间需要8^15*5*5,明显不够,又鉴于最大深 ...

  4. [1015][JSOI2008]星球大战starwar(并查集)

    1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2124  Solved: 909[Submit] ...

  5. [bzoj 1004][HNOI 2008]Cards(Burnside引理+DP)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1004 分析: 1.确定方向:肯定是组合数学问题,不是Polya就是Burnside,然后题目上 ...

  6. shell中的流程控制

    一.if的使用 判断磁盘使用率,如果超过要求值就直接报警 数据库备份 apache服务器启动检测(nmap工具需要安装) 多重条件判断 二.case的使用 三.for使用 字符串循环,in后面的内容以 ...

  7. Python学习日记

    江林楠学习了一下午后给大家呈现的20分钟速成Python—— 一些基本的语法:1.python无变量声明 直接a = []即可.2.python为对齐语言,用制表符表示语句块的嵌套.3.python语 ...

  8. php empty()和isset()的区别

    在使用 php 编写页面程序时,我经常使用变量处理函数判断 php 页面尾部参数的某个变量值是否为空,开始的时候我习惯了使用 empty() 函数,却发现了一些问题,因此改用 isset() 函数,问 ...

  9. C语言浮点数除法可以精确到多少位小数

    double型的两个数相除,得到的浮点数能精确到多少位呢..用我家电脑做了个实验,编译器是Code::Blocks 13.12. 然后用电脑自带的计算器算的结果和C语言算的结果比较如图. 第一例里a= ...

  10. 淘宝中的UV,PV,IPV

    1.  UV & PV UV: 店铺各页面的访问人数,一个用户在一天内多次访问店铺被记为一个访客(去重) ; Unique visitors PV: 店铺内所有页面的浏览总量(次数累加); p ...