Submission #664872
Source Code Expand
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <complex>
#include <string>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
#include <cassert>
using namespace std;
typedef pair<int,int> P;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define INF 2000000000
#define sz(x) ((int)(x).size())
#define fi first
#define sec second
#define SORT(x) sort((x).begin(),(x).end())
#define all(x) (x).begin(),(x).end()
#define rep(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define repn(i,a,n) for(int (i)=(a);(i)<(int)(n);(i)++)
#define EQ(a,b) (abs((a)-(b))<eps)
// Link Cut Tree
// 木をHeavy-Light decompositionし、各pathをsplay木(平衡二分木)で管理
// 各splay木において、左にあるほど根に近い。
// root以外はspaceships,road_developmentでverify済
// LinkCutTreeは本来、(根方向に有向な)有向木を扱うものであるから、無向木を扱う際は
// linkやcutする時に注意深くevertを行うこと。
// pathに対する様々な操作が可能。AからBへのpathに対する操作を行いたい時、
// Aをevertし、BをexposeすることでAとBは同じsplay木に含まれる様になる。
// (さらに,Bはexposeによってsplay木の根となっている)
// よって、各splay木内においてSegtree同様にデータを保持しておけば(遅延評価等も),
// 任意のpathに対するクエリに答えられる。
// is_root,rotr,rotl,splay,expose,cut,link,root,lcaはいじる必要ない。
// update,toggle,push,set,getを適宜変更して用いること。
// 対応クエリ:
// 根までのpathのコストを全てxにする
// 根までのpathのコストの和を求める
// 左の子孫が実際の先祖,右の子孫が実際の子孫
struct Node{
Node *pp,*lp,*rp;
int id; // 頂点番号 初期化時に必ず指定すること。
int size; // 自分の属するsplay木における自分以下の頂点数
bool rev; // 反転フラグ
typedef int val_t; // 適宜long longに変更すること。
struct Data{
val_t val,sum,lazy;
}data;
Node(int id):pp(NULL),lp(NULL),rp(NULL),id(id),size(1){}
Node(int id,val_t v):pp(NULL),lp(NULL),rp(NULL),id(id){
data.val = v;
data.sum = v;
data.lazy = -1;
}
void update(){ //子から、size,dataを更新する
if(this==NULL)return;
size = 1;
data.sum = data.val;
if(lp!=NULL){
data.sum += lp->data.sum;
size += lp->size;
}
if(rp!=NULL){
data.sum += rp->data.sum;
size += rp->size;
}
return;
}
void lazy_evaluate(val_t x){
data.val = x;
data.sum = x*size;
data.lazy = x;
}
void toggle(){ //lpとrpを交換した際に変わる値もここに記述
assert(this!=NULL);
swap(lp,rp);
rev ^= true;
}
void push(){
// 遅延評価とrevフラグの伝搬を行う。
// もちろんrevよりも先に遅延評価しないと意味がない
bool lch = (lp!=NULL),rch = (rp!=NULL);
if(data.lazy!=-1){
if(lch){
lp->lazy_evaluate(data.lazy);
}
if(rch){
rp->lazy_evaluate(data.lazy);
}
data.lazy=-1;
}
if(rev){
if(lch){
lp->toggle();
}
if(rch){
rp->toggle();
}
rev = false;
}
}
void push_all(){
// splay前に一気に根までpushする。
// stack overflowする可能性があるので、する場合は
// 下のsplayを使用すること。
if(!is_root())pp->push_all();
push();
}
bool is_root(){ // splay木の根か
return !pp||(pp->lp!=this&&pp->rp!=this);
}
void rotr(){ // splay木 右回転
Node *q=pp,*r=q->pp;
if((q->lp=rp))rp->pp=q;
rp=q;q->pp=this;
q->update();
update();
if((pp=r)){
if(r->lp==q)r->lp=this;
if(r->rp==q)r->rp=this;
}
r->update();
}
void rotl(){ // splay木 左回転
Node *q=pp,*r=q->pp;
if((q->rp=lp))lp->pp=q;
lp=q;q->pp=this;
q->update();
update();
if((pp=r)){
if(r->lp==q)r->lp=this;
if(r->rp==q)r->rp=this;
}
r->update();
}
/*void splay(){ // splay操作。 頂点を属するsplay木の根に持っていく
push_all();
while(!is_root()){
Node *q=pp;
if(q->is_root()){
if(q->lp==this)rotr();
else rotl();
}else{
Node *r=q->pp;
if(r->lp==q){
if(q->lp==this){q->rotr();rotr();}
else {rotl();rotr();}
}else{
if(q->rp==this){q->rotl();rotl();}
else {rotr();rotl();}
}
}
}
}*/
void splay(){ // stack overflow する時用。こっちのほうが早いかも。
push();
while(!is_root()){
Node *q=pp;
if(q->is_root()){
q->push();push();
if(q->lp==this)rotr();
else rotl();
}else{
Node *r=q->pp;
r->push();q->push();push();
if(r->lp==q){
if(q->lp==this){q->rotr();rotr();}
else {rotl();rotr();}
}else{
if(q->rp==this){q->rotl();rotl();}
else {rotr();rotl();}
}
}
}
}
void expose(){ // 実際の木の根を含むsplay木に属する様に変形する
// 自分の子孫とは別のsplay木に属することになる、
// すなわちexpose後のpath分解において自分が自分を含むpathの中で最も深くなる
// のは仕様(lca,evertが楽)
Node *rp=NULL;
for(Node *p=this;p;p=p->pp){
p->splay();
p->rp=rp;
p->update();
rp=p;
}
splay(); // 一応根に持っていっとくと色々便利(cutとかlinkの時)
}
// 無向木を扱う際、link,cut時に注意深くevertを行うこと。
void cut(){ // 実際の木において親への辺をcut
expose();
Node *p=lp;
if(p!=NULL){
lp=NULL;
p->pp=NULL;
}
}
void link(Node *p){ // 実際の木においてpへ辺を張る(pのほうが親)
expose(); // 既に同じ木に属してるもの同士をlinkするとヤバいから注意。
p->expose();
pp=p;
p->rp=this;
}
void evert(){
//exposeで自分の子孫とは別のsplay木に属することになるからこれでOK
expose();
toggle();
}
Node* root(){ // 実際の木において、このnodeが所属する木の根
expose();
Node* u = this;
while(u->lp)u=u->lp;
u->splay();
return u;
}
Node* lca(Node *p){
p->expose();
expose();
Node *ret=p;
while(p->pp != NULL){
//exposeで自分の子孫とは別のsplay木に属することになるからこれでOK
if(p->is_root())ret=p->pp;
p=p->pp;
}
return (this==p)?ret:NULL;
}
val_t get(){ // 根までのpath上のコストの和
expose();
return data.sum;
}
void set(val_t x){ // 根までのpath上のコストを全てxにする
expose();
lazy_evaluate(x);
}
};
Node* nodev[100005];
Node* nodee[100005];
/*int num(Node* x){
if(x==NULL)return -1;
else return x->id;
}
void showtree(int n){
for(int i=0;i<n;i++)printf("%d p %d l %d r %d rev %d\n",i,num(nodev[i]->pp),num(nodev[i]->lp),num(nodev[i]->rp),nodev[i]->rev);
}*/
int N,Q;
int main()
{
scanf("%d %d",&N,&Q);
for(int i=0;i<N;i++)nodev[i]=new Node(i,0);
for(int i=0;i<N;i++)nodee[i]=new Node(i,1);
int cnt = 0;
for(int i=0;i<Q;i++)
{
int T,A,B;
scanf("%d %d %d",&T,&A,&B);
A--;B--;
if(T==1){
if((nodev[A]->lca(nodev[B]))==NULL){
nodev[A]->evert();
nodev[A]->link(nodee[cnt]);
nodee[cnt]->link(nodev[B]);
cnt++;
}else{
nodev[A]->evert();
nodev[B]->set(0);
}
}else{
if((nodev[A]->lca(nodev[B]))==NULL)printf("-1\n");
else{
nodev[A]->evert();
printf("%d\n",nodev[B]->get());
}
}
}
return 0;
}
Submission Info
Submission Time
2016-03-19 01:18:14+0900
Task
G - 道路整備
User
okura
Language
C++ (G++ 4.6.4)
Score
100
Code Size
7913 Byte
Status
AC
Exec Time
902 ms
Memory
15244 KB
Compile Error
./Main.cpp: In function ‘int main()’:
./Main.cpp:274:22: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
./Main.cpp:281:29: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
Judge Result
Set Name
Subtask01
Subtask02
Subtask03
Subtask04
Subtask05
Score / Max Score
10 / 10
25 / 25
25 / 25
25 / 25
15 / 15
Status
Set Name
Test Cases
Subtask01
sample-01.txt, sample-02.txt, sample-03.txt, 01-01.txt, 01-02.txt, 01-03.txt, 01-04.txt, 01-05.txt, 01-06.txt, 01-07.txt, 01-08.txt
Subtask02
02-01.txt, 02-02.txt, 02-03.txt, 02-04.txt, 02-05.txt, 02-06.txt, 02-07.txt, 02-08.txt, 02-09.txt, 02-10.txt, 02-11.txt, 02-12.txt, 02-13.txt, 02-14.txt
Subtask03
sample-01.txt, sample-02.txt, sample-03.txt, 03-01.txt, 03-02.txt, 03-03.txt, 03-04.txt, 03-05.txt, 03-06.txt, 03-07.txt, 03-08.txt, 03-09.txt, 03-10.txt, 03-11.txt, 03-12.txt, 03-13.txt, 03-14.txt
Subtask04
sample-01.txt, sample-02.txt, sample-03.txt, 04-01.txt, 04-02.txt, 04-03.txt, 04-04.txt, 04-05.txt, 04-06.txt, 04-07.txt, 04-08.txt, 04-09.txt, 04-10.txt, 04-11.txt, 04-12.txt
Subtask05
sample-01.txt, sample-02.txt, sample-03.txt, 01-01.txt, 01-02.txt, 01-03.txt, 01-04.txt, 01-05.txt, 01-06.txt, 01-07.txt, 01-08.txt, 02-01.txt, 02-02.txt, 02-03.txt, 02-04.txt, 02-05.txt, 02-06.txt, 02-07.txt, 02-08.txt, 02-09.txt, 02-10.txt, 02-11.txt, 02-12.txt, 02-13.txt, 02-14.txt, 03-01.txt, 03-02.txt, 03-03.txt, 03-04.txt, 03-05.txt, 03-06.txt, 03-07.txt, 03-08.txt, 03-09.txt, 03-10.txt, 03-11.txt, 03-12.txt, 03-13.txt, 03-14.txt, 04-01.txt, 04-02.txt, 04-03.txt, 04-04.txt, 04-05.txt, 04-06.txt, 04-07.txt, 04-08.txt, 04-09.txt, 04-10.txt, 04-11.txt, 04-12.txt, 05-01.txt, 05-02.txt, 05-03.txt, 05-04.txt, 05-05.txt, 05-06.txt, 05-07.txt, 05-08.txt, 05-09.txt, 05-10.txt, 05-11.txt, 05-12.txt, 05-13.txt
Case Name
Status
Exec Time
Memory
01-01.txt
AC
165 ms
1264 KB
01-02.txt
AC
34 ms
1192 KB
01-03.txt
AC
36 ms
1220 KB
01-04.txt
AC
35 ms
1272 KB
01-05.txt
AC
35 ms
1300 KB
01-06.txt
AC
36 ms
1296 KB
01-07.txt
AC
34 ms
1268 KB
01-08.txt
AC
36 ms
1220 KB
02-01.txt
AC
313 ms
15152 KB
02-02.txt
AC
670 ms
15216 KB
02-03.txt
AC
836 ms
15220 KB
02-04.txt
AC
849 ms
15192 KB
02-05.txt
AC
792 ms
15224 KB
02-06.txt
AC
748 ms
15156 KB
02-07.txt
AC
639 ms
15232 KB
02-08.txt
AC
767 ms
15164 KB
02-09.txt
AC
599 ms
15176 KB
02-10.txt
AC
746 ms
15224 KB
02-11.txt
AC
735 ms
15156 KB
02-12.txt
AC
776 ms
15156 KB
02-13.txt
AC
740 ms
15192 KB
02-14.txt
AC
752 ms
15176 KB
03-01.txt
AC
297 ms
15156 KB
03-02.txt
AC
624 ms
15220 KB
03-03.txt
AC
779 ms
15220 KB
03-04.txt
AC
813 ms
15212 KB
03-05.txt
AC
501 ms
15220 KB
03-06.txt
AC
822 ms
15224 KB
03-07.txt
AC
274 ms
15180 KB
03-08.txt
AC
802 ms
15216 KB
03-09.txt
AC
761 ms
15152 KB
03-10.txt
AC
786 ms
15152 KB
03-11.txt
AC
289 ms
15176 KB
03-12.txt
AC
785 ms
15180 KB
03-13.txt
AC
788 ms
15176 KB
03-14.txt
AC
665 ms
15220 KB
04-01.txt
AC
212 ms
15156 KB
04-02.txt
AC
421 ms
15152 KB
04-03.txt
AC
523 ms
15176 KB
04-04.txt
AC
517 ms
15160 KB
04-05.txt
AC
621 ms
15220 KB
04-06.txt
AC
826 ms
15228 KB
04-07.txt
AC
150 ms
15244 KB
04-08.txt
AC
151 ms
15188 KB
04-09.txt
AC
195 ms
15168 KB
04-10.txt
AC
191 ms
15172 KB
04-11.txt
AC
680 ms
15220 KB
04-12.txt
AC
786 ms
15216 KB
05-01.txt
AC
305 ms
15220 KB
05-02.txt
AC
603 ms
15176 KB
05-03.txt
AC
872 ms
15176 KB
05-04.txt
AC
902 ms
15152 KB
05-05.txt
AC
262 ms
15124 KB
05-06.txt
AC
469 ms
15216 KB
05-07.txt
AC
722 ms
15224 KB
05-08.txt
AC
753 ms
15220 KB
05-09.txt
AC
793 ms
15212 KB
05-10.txt
AC
733 ms
15144 KB
05-11.txt
AC
716 ms
15216 KB
05-12.txt
AC
663 ms
15196 KB
05-13.txt
AC
684 ms
15156 KB
sample-01.txt
AC
31 ms
1116 KB
sample-02.txt
AC
31 ms
1204 KB
sample-03.txt
AC
33 ms
1140 KB