Submission #9654701
Source Code Expand
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include <bits/stdc++.h>
using namespace std;
#define REP(i,n) for(int i=0; i<(int)(n); i++)
#define DEBUG(x) cerr << #x << ": " << (x) << endl
namespace Tree234 {
// no function
using T = char;
const T e = '\0';
T f(T a, T b){
return b;
}
// template begin
struct Node;
// using Ptr = Node*;
using Ptr = shared_ptr<Node>;
struct Node {
int rank, size, cnt;
Ptr ch[4];
bool isLeaf() const {return cnt == 0;}
bool is4Node() const {return cnt == 4;}
T val;
Node(T v=e):rank(0),size(1),ch{nullptr,nullptr,nullptr,nullptr},cnt(0),val(v){}
Node(Ptr that){
rank = that->rank; size = that->size; cnt = that->cnt;
REP(i,cnt)ch[i] = that->ch[i];
val = that->val;
}
};
// const int HIST_LIM = 8'000'000;
// const int HIST_REST = 50'000;
// Node pool[HIST_LIM + HIST_REST];
// int pool_tail = 0;
Ptr newNode(T v=e){
// Ptr ret = &pool[pool_tail++];
// *ret = Node(v);
// return ret;
return make_shared<Node>(v);
}
Ptr newNode(Ptr node){
// Ptr ret = &pool[pool_tail++];
// *ret = Node(node);
// return ret;
return make_shared<Node>(node);
}
Ptr update(Ptr node){ // ephemeral
if(node == nullptr)return nullptr;
if(node->isLeaf())return node;
node->rank = node->ch[0]->rank + 1;
node->size = 0;
node->val = e;
REP(i,node->cnt){
node->size += node->ch[i]->size;
node->val = f(node->val, node->ch[i]->val);
}
return node;
}
void debug(Ptr node){
if(node == nullptr){
cerr << "-";
}else if(node->isLeaf()){
cerr << node->val;
}else{
cerr << "[" << node->val << "]";
cerr << "(";
REP(i,node->cnt){
debug(node->ch[i]);
cerr << ",";
}
cerr << ")";
}
}
Ptr splitRoot(Ptr root){
assert(root != nullptr && root->is4Node());
Ptr ret = newNode(root);
Ptr lft = newNode(), rgt = newNode();
lft->cnt = rgt->cnt = 2;
lft->ch[0] = ret->ch[0]; lft->ch[1] = ret->ch[1];
rgt->ch[0] = ret->ch[2]; rgt->ch[1] = ret->ch[3];
lft = update(lft); rgt = update(rgt);
ret->cnt = 2;
ret->ch[0] = lft; ret->ch[1] = rgt;
return update(ret);
}
Ptr splitNode(Ptr node, int k){
assert(node != nullptr && !node->is4Node() && k < node->cnt && node->ch[k] != nullptr && node->ch[k]->is4Node());
node = newNode(node);
Ptr lft = newNode(node->ch[k]);
Ptr rgt = newNode();
lft->cnt = rgt->cnt = 2;
lft->ch[0] = lft->ch[0]; lft->ch[1] = lft->ch[1];
rgt->ch[0] = lft->ch[2]; rgt->ch[1] = lft->ch[3];
move_backward(node->ch + k+1, node->ch + node->cnt, node->ch + node->cnt + 1);
node->cnt += 1;
node->ch[k] = update(lft); node->ch[k+1] = update(rgt);
return update(node);
}
Ptr _merge(Ptr lft, Ptr rgt, bool rev){
assert(lft->rank > rgt->rank && !lft->is4Node());
lft = newNode(lft);
if(lft->rank == rgt->rank + 1){
if(rev)move_backward(lft->ch, lft->ch + lft->cnt, lft->ch + lft->cnt + 1);
lft->ch[!rev ? lft->cnt : 0] = rgt;
lft->cnt += 1;
return update(lft);
}else{
int k = !rev ? lft->cnt-1 : 0;
if(lft->ch[k]->is4Node()){
lft = splitNode(lft, k);
k = !rev ? lft->cnt-1 : 0;
}
lft->ch[k] = _merge(lft->ch[k], rgt, rev);
return update(lft);
}
}
Ptr merge(Ptr lft, Ptr rgt){
if(lft == nullptr)return rgt;
if(rgt == nullptr)return lft;
if(lft->rank == rgt->rank){
Ptr ret = newNode();
ret->cnt = 2;
ret->ch[0] = lft; ret->ch[1] = rgt;
return update(ret);
}else{
if(lft->rank > rgt->rank){
if(lft->is4Node()){
lft = splitRoot(lft);
}
return _merge(lft, rgt, false);
}else{
if(rgt->is4Node()){
rgt = splitRoot(rgt);
}
return _merge(rgt, lft, true);
}
}
}
pair<Ptr,Ptr> split(Ptr node, int k){
if(node == nullptr)return make_pair((Ptr)nullptr, (Ptr)nullptr);
assert(k <= node->size);
if(k==0){
return make_pair((Ptr)nullptr, node);
}else if(k == node->size){
return make_pair(node, (Ptr)nullptr);
}
assert(!node->isLeaf());
Ptr leftside = nullptr;
Ptr rightside = nullptr;
REP(to, node->cnt){
int sz = node->ch[to]->size;
if(k <= sz){
pair<Ptr,Ptr> rec = split(node->ch[to], k);
leftside = merge(leftside, rec.first);
rightside = merge(rightside, rec.second);
while(++to < node->cnt){
rightside = merge(rightside, node->ch[to]);
}
// free(node);
return make_pair(leftside, rightside);
}else{
leftside = merge(leftside, node->ch[to]);
k -= sz;
}
}
assert(false);
}
Ptr insert(Ptr node, int k, T x){
pair<Ptr,Ptr> P = split(node, k);
Ptr nw = newNode(x);
return merge(merge(P.first, nw), P.second);
}
Ptr erase(Ptr node, int k){
pair<Ptr,Ptr> P1, P2;
P1 = split(node, k);
P2 = split(P1.second, 1);
// free(P2.first);
return merge(P1.first, P2.second);
}
T rangeGet(Ptr node, int l, int r){
if(node == nullptr)return e;
assert(0<=l && l<=r && r<=node->size);
if(r-l == 0)return e;
if(r-l == node->size)return node->val;
assert(!node->isLeaf());
T ret = e;
REP(to, node->cnt){
int sz = node->ch[to]->size;
if(l<sz && r-l != 0){
T chval;
chval = rangeGet(node->ch[to], l, min(r, sz));
ret = f(ret, chval);
}
l = max(0, l - sz); r = max(0, r - sz);
}
return ret;
}
T kth(Ptr node, int k){
return rangeGet(node, k, k+1);
}
Ptr construct(T *arr, int n){
vector<Ptr> v(n, nullptr);
REP(i,n)v[i] = Tree234::newNode(arr[i]);
while(v.size() > 1){
if(v.size()%2 == 1)v.push_back(nullptr);
int m = v.size();
vector<Ptr> w(m/2, nullptr);
REP(i,m/2){
w[i] = Tree234::merge(v[2*i+0], v[2*i+1]);
}
swap(v, w);
}
return v[0];
}
// template end
};
// https://atcoder.jp/contests/joisc2012/tasks/joisc2012_copypaste
int m, q;
char s[1'252'830];
int main(){
scanf("%d%s%d",&m,s,&q);
int n = strlen(s);
// initialize
using Node = Tree234::Node;
using Ptr = Tree234::Ptr;
Ptr root = Tree234::construct(s, n);
// query
while(q--){
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
Ptr substr = Tree234::split(Tree234::split(root, r).first, l).second;
pair<Ptr,Ptr> splitted = Tree234::split(root, x);
root = Tree234::merge(Tree234::merge(splitted.first, substr), splitted.second);
if(root->size > m){
root = Tree234::split(root, m).first;
}
}
int sz = root->size;
REP(i,sz)putchar(Tree234::kth(root, i));
puts("");
return 0;
}
Submission Info
Submission Time
2020-01-21 03:52:25
Task
copypaste - コピー&ペースト
User
rickytheta
Language
C++14 (GCC 5.4.1)
Score
90
Code Size
7988 Byte
Status
TLE
Exec Time
17855 ms
Memory
222060 KB
Compile Error
./Main.cpp: In function ‘int main()’:
./Main.cpp:223:28: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%d%s%d",&m,s,&q);
^
./Main.cpp:232:33: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%d%d%d",&l,&r,&x);
^
Judge Result
Set Name
Set01
Set02
Set03
Set04
Set05
Set06
Set07
Set08
Set09
Set10
Score / Max Score
10 / 10
10 / 10
10 / 10
10 / 10
10 / 10
10 / 10
10 / 10
10 / 10
10 / 10
0 / 10
Status
Set Name
Test Cases
Set01
01-01, 01-02, 01-03, 01-04
Set02
02-01, 02-02, 02-03
Set03
03-01, 03-02, 03-03
Set04
04-01, 04-02
Set05
05-01, 05-02
Set06
06-01, 06-02
Set07
07-01, 07-02
Set08
08-01, 08-02
Set09
09-01, 09-02
Set10
10-01, 10-02, 10-03, 10-04
Case Name
Status
Exec Time
Memory
01-01
AC
1503 ms
640 KB
01-02
AC
1408 ms
22356 KB
01-03
AC
36 ms
1792 KB
01-04
AC
1 ms
256 KB
02-01
AC
3203 ms
640 KB
02-02
AC
3028 ms
44332 KB
02-03
AC
3143 ms
640 KB
03-01
AC
4980 ms
896 KB
03-02
AC
4641 ms
68252 KB
03-03
AC
4927 ms
768 KB
04-01
AC
6820 ms
896 KB
04-02
AC
6475 ms
88540 KB
05-01
AC
8720 ms
1024 KB
05-02
AC
8247 ms
110644 KB
06-01
AC
10570 ms
1152 KB
06-02
AC
10063 ms
134160 KB
07-01
AC
12519 ms
1280 KB
07-02
AC
11970 ms
154724 KB
08-01
AC
14470 ms
1408 KB
08-02
AC
13746 ms
176828 KB
09-01
AC
16587 ms
1536 KB
09-02
AC
15790 ms
200088 KB
10-01
TLE
17855 ms
640 KB
10-02
TLE
17538 ms
222060 KB
10-03
TLE
17855 ms
640 KB
10-04
AC
12215 ms
222060 KB