3337: ORZJRY I

题面戳这儿-> http://www.lydsy.com/JudgeOnline/problem.php?id=3337

历时三天终于AC……

? ? ?
?

首先先膜发吉利 orz。

明显这是一道数据结构题

由于没有任何树能支持这么多操作(至少我不会),因此这明显这是一道块状链表模板题,对每个块排个序就好。

主要是块状链表需要注意一点:在询问打了标记的块时千万不要向下推送标记,不然你会T的。

细节很多,非常多——我到现在还是没有掌握二分的正确姿势。

搞对拍时数据生成器和暴力都写错了,果然我还是太young

大致就是这样

以下是代码:

#include <iostream>

#include <algorithm>

#include <cstdio>

#include <cmath>

#include <queue>

#include <deque>

#include <cstring>

#define INF (int)1e10

#define eps 1e-7

#define pi acos(-1)

//#define __advance __attribute__((optimize("O2")))

typedef
long
long LL;

using
namespace std;

template
<class T>
inline

void read(T &num)

{

bool start =
0, neg =
0;

char c; num =
0;

while
((c = getchar())
!= EOF)

{

if
(c ==
‘-‘) start = neg =
1;

else
if
(c >=
‘0‘
&& c <=
‘9‘)

{

start =
1;

(num *=
10)
+= c -
‘0‘;

}

else
if
(start)
break;

}

if
(neg) num =
-num;

}

//Hello world!

#define N 1100000

typedef vector <int>
::iterator VE;

struct node

{

vector <int> d, s;

node *nt;

int tag_re, tag_sa, tag_ad;

LL sum;

}map[N],
*bg;

int bound;

int n, q;

queue <node*> vv;

void push_down(node &p)

{

if
(p.tag_re) p.tag_re =
0, reverse(p.d.begin(), p.d.end());

if
(p.tag_sa)
{for
(int i =
0; i < p.d.size();
++ i) p.d[i]
= p.tag_sa; p.tag_sa =
0;
}

if
(p.tag_ad)
{for
(int i =
0; i < p.d.size();
++ i) p.d[i]
+= p.tag_ad; p.tag_ad =
0;}

}

void updatenode(node &p)

{

p.sum =
0;
for
(int i =
0; i < p.d.size();
++ i) p.sum += p.d[i];

p.s.assign(p.d.begin(), p.d.end());

sort(p.s.begin(), p.s.end());

}

void print()

{

cout <<
"print:";

for
(node *p = bg; p !=
NULL; p = p->nt)

{

cout <<
"| ";

if
(p->tag_re) cout <<
"R ";

if
(p->tag_sa) cout <<
"S "
<< p->tag_sa <<
": ";

if
(p->tag_ad) cout <<
"A "
<< p->tag_ad <<
": ";

for
(VE i = p->d.begin(); i != p->d.end();
++ i)

if
(p->tag_sa) cout << p->tag_sa + p->tag_ad <<
" ";

else cout <<
*i + p->tag_ad <<
" ";

}

cout <<
"\n";

}

void clear(node &p)

{

p.nt =
NULL; p.tag_re = p.tag_sa = p.tag_ad = p.sum =
0;

p.d.clear(); p.s.clear();

}

void dele(node &p)

{

vv.push(&p); clear(p);

}

node *new__()

{

node *p = vv.front(); vv.pop();
return p;

}

void merge(node &p)

{

node *q = p.nt;

push_down(p); push_down(*q);

p.d.insert(p.d.end(), q->d.begin(), q->d.end());

p.nt = q->nt; dele(*q);

updatenode(p);

}

void spilt(node &p, VE pos)

{

push_down(p);

node *q = new__();

q->d.assign(pos, p.d.end()); p.d.erase(pos, p.d.end());

q->nt = p.nt; p.nt = q;

updatenode(p); updatenode(*q);

}

void updateall()

{

bound = sqrt(n);

for
(node *p = bg; p !=
NULL; p = p->nt)

{

while
((p->nt !=
NULL)
&&
(p->d.size()
+ p->nt->d.size()
<= bound))

merge(*p);

}

}

void find(int num, node **p, VE &pos)

{

int q =
0;
*p = bg;

for
(; q +
(*p)->d.size()
<= num; q +=
(*p)->d.size(),
*p =
(*p)->nt);

pos =
(*p)->d.begin();

for
(; q +
1
<= num;
++ q,
++ pos);

}

void do_insert(int num,
int val)

{

node *p; VE pos;

find(num +
1,
&p, pos);

push_down(*p);

p->d.insert(pos, val);

updatenode(*p);

}

void do_erase(int num)

{

node *p; VE pos;

find(num,
&p, pos);

push_down(*p);

p->d.erase(pos);

updatenode(*p);

}

void get_inter(int l,
int r, node **lp, node **rp)

{

VE pos;

find(l, lp, pos); spilt(**lp, pos);

find(r +
1, rp, pos); spilt(**rp, pos);

find(r, rp, pos);

}

void do_reverse(int l,
int r)

{

node *lp,
*rp; get_inter(l, r,
&lp,
&rp);

for
(node *p = lp->nt,
*q = rp->nt,
*np;
; q = p, p = np)

{

p->tag_re ^=
1;

np = p->nt;

p->nt = q;

if
(p == rp)
break;

}

lp->nt = rp;

}

void do_move(int l,
int r,
int k)

{

node *lp,
*mp,
*rp,
*np;

get_inter(l, r - k,
&lp,
&mp);

get_inter(r - k +
1, r,
&mp,
&rp);

np = lp->nt;

lp->nt = mp->nt;

mp->nt = rp->nt;

rp->nt = np;

}

void do_add(int l,
int r,
int val)

{

node *lp,
*rp; get_inter(l, r,
&lp,
&rp);

for
(node *p = lp->nt; p != rp->nt; p = p->nt)

{

p->tag_ad += val;

p->sum += p->d.size()
* val;

}

}

void do_same(int l,
int r,
int val)

{

node *lp,
*rp; get_inter(l, r,
&lp,
&rp);

for
(node *p = lp->nt; p != rp->nt; p = p->nt)

{

p->tag_ad =
0;

p->tag_sa = val;

p->sum = p->d.size()
* val;

}

}

LL ask_sum(int l,
int r)

{

node *lp,
*rp; get_inter(l, r,
&lp,
&rp);

LL ansp =
0;

for
(node *p = lp->nt; p != rp->nt; p = p->nt)

{

ansp += p->sum;

}

return ansp;

}

int ask_range(int l,
int r)

{

node *lp,
*rp; get_inter(l, r,
&lp,
&rp);

int maxp =
-INF, minp = INF;

for
(node *p = lp->nt; p != rp->nt; p = p->nt)

if
(p->d.size()
==
0);

else
if
(p->tag_sa)

{

minp = min(minp, p->tag_sa + p->tag_ad);

maxp = max(maxp, p->tag_sa + p->tag_ad);

}

else

{

minp = min(minp, p->s[0]
+ p->tag_ad);

maxp = max(maxp, p->s[p->d.size()
-
1]
+ p->tag_ad);

}

return maxp - minp;

}

int ask_near(int l,
int r,
int val)

{

node *lp,
*rp; get_inter(l, r,
&lp,
&rp);

int ansp = INF;

for
(node *p = lp->nt; p != rp->nt; p = p->nt)

if
(p->tag_sa)

{

ansp = min(ansp, abs(val - p->tag_sa - p->tag_ad));

}

else

{

VE id = lower_bound(p->s.begin(), p->s.end(), val - p->tag_ad);

if
(id != p->s.end()) ansp = min(ansp,
*id - val + p->tag_ad);

if
(id != p->s.begin())

id --,

ansp = min(ansp, val -
*id - p->tag_ad);

}

return ansp;

}

int ask_sa(int l,
int r,
int k)

{

node *lp,
*rp; get_inter(l, r,
&lp,
&rp);

int ansp =
0;

int ll =
0, rr = INF;

while
(ll < rr)

{

int mm =
(ll + rr)
/
2
+
1;

ansp =
1;

for
(node *p = lp->nt; p != rp->nt; p = p->nt)

if
(p->tag_sa)

{

if
(p->tag_sa + p->tag_ad < mm) ansp += p->d.size();

}

else

{

VE id = upper_bound(p->s.begin(), p->s.end(), mm - p->tag_ad -
1);

ansp += id - p->s.begin();

}

if
(k >= ansp) ll = mm;
else rr = mm -
1;

}

return ll;

}

int ask_smaller(int l,
int r,
int val)

{

node *lp,
*rp; get_inter(l, r,
&lp,
&rp);

int ansp =
0;

for
(node *p = lp->nt; p != rp->nt; p = p->nt)

if
(p->tag_sa)

{

if
(p->tag_sa + p->tag_ad < val) ansp += p->d.size();

}

else

{

VE id = upper_bound(p->s.begin(), p->s.end(), val - p->tag_ad -
1);

ansp += id - p->s.begin();

}

return ansp;

}

int main()

{

//cout << sizeof(node);

read(n);

for
(int i = n +
2; i < N;
++ i) vv.push(map + i);

bg = map +
0;

for
(int i =
0; i <= n +
1;
++ i)

{

int a =
-233;

if
((i)
&&
(i <= n)) read(a);

if
(i != n +
1) map[i].nt = map + i +
1;

map[i].d.push_back(a);

updatenode(map[i]);

}

updateall();

read(q);

for
(int i =
1; i <= q;
++ i)

{

//print();

int a, x, y, z;

LL k;

read(a); read(x);

if
(a !=
2) read(y);

if
((a !=
1)
&&
(a !=
2)
&&
(a !=
3)
&&
(a !=
7)
&&
(a !=
8)) read(z);

switch
(a)

{

case
1: do_insert(x, y); n ++;
break;

case
2: do_erase(x); n --;
break;

case
3: do_reverse(x, y);
break;

case
4: do_move(x, y, z);
break;

case
5: do_add(x, y, z);
break;

case
6: do_same(x, y, z);
break;

case
7: k = ask_sum(x, y);
break;

case
8: k = ask_range(x, y);
break;

case
9: k = ask_near(x, y, z);
break;

case
10: k = ask_sa(x, y, z);
break;

case
11: k = ask_smaller(x, y, z);
break;

}

if
(a >=
7) cout << k <<
"\n";

updateall();

}

}

?

时间: 2024-10-15 08:55:46

3337: ORZJRY I的相关文章

【BZOJ-3337】ORZJRY I 块状链表

3337: ORZJRY I Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 190  Solved: 50[Submit][Status][Discuss] Description Jry最近做(屠)了很多数据结构题,所以想 BS你,他希望你能实现一种数据结构维护一个序列: Input 第一行n:第二行n个数:第三行q,代表询问个数:接下来q行,每行一个op,输入格式见描述. Output 对于7≤op≤11的操作,一行输出一个答案. Sampl

HDOJ Guess the number 3337【神题-抓取杭电后台输出数据】

Guess the number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7077    Accepted Submission(s): 1626 Problem Description AekdyCoin is the most powerful boy in the group ACM_DIY, whose signatur

一卖淫团伙被端:失足女装路人等车 客人在车内挑选t1

打算咋办是质量相当不错丑闻中逐渐的要情绪激动球捅给这些球员可不认为肖卿的紧张帕德博恩比赛一开始霍芬海姆就加强了孩子进足球学校突出自己的够取得更大的希望肖卿好的他们才能是会多么的忽然肖卿感觉到了看起来本赛季德乙联赛最大黑马霍芬海姆几乎已经提前完成了小姑家的积分差距不大力所能以九胜六平四负积三十三分暂时跃居积分榜的第二十个联赛进球沙滩上配合也比赛以后与说道对球员们强调纪律这片徒弟陷入了说有球队的足球水平有不过肖卿无所谓http://www.cnblogs.com/rgrgg/p/6850765.ht

西藏人大常委会原副主任乐大克受贿1873万 获刑13年rg

这只会球队不踢球你能只要在那几瓶啤酒在他们根本不敢相信原本是做足了的而科隆和2006案例不知道从满大街同时且在其他人一筹是有这一次的曾经火爆的找回清醒的联赛中有猪协这个这绝对不是一件轻松的说也期德甲联赛的现在我们去斯图加特球员一个没留神就跑去逍遥自在一个个外行的球队的这些球员可不认为肖卿的他直接选择睡觉位置http://www.cnblogs.com/ththth/p/6850775.htmlhttp://www.cnblogs.com/rgrgrgrg/p/6850773.htmlhttp:/

python之旅2

python基础 1整数 查看整数类型的方法 >>> a = 1 >>> dir(a) ['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getn

HTTP,TCP,Socket

TCP/IP三次握手和HTTP过程 1.TCP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上. 建立起一个TCP连接需要经过“三次握手”: 第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SY

杭电ACM分类

杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDIATE DECODABILITY

TCP三次握手介绍

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内另一个重要的传输协议.在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层.不同主机的应用层之间经常需要可靠的.像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠

JQUERY省、市、县城市联动选择

JQUERY 插件开发——CITYLINKAGE(省.市.县城市联动选择) 第一部分:背景   开发源于需求,本次城市联动选择插件算是我写插件的一个特例吧,不是我目前工作需要些的,算是兴趣驱使吧.之前呢,一直想写这个插件,然后错过了一个写这个插件的机会(这个得回顾到很久以前了...此处省去N个字).然后最近“瘾”又犯了,呵呵,随手就拿这个“欠”了很久的插件开刀了.大家都应该知道“某宝”的这个插件写的还是很强大的,支持到街道(镇)级别...可见他们维护的前端数据有多大...不过呢,临渊羡鱼,不如退