中學生資料結構題

2021-07-31 15:32:14 字數 1683 閱讀 9477

給一棵n個帶點權節點(初始為0)的樹

有三種操作:

1,對一條路徑上的點的點權全部增加乙個數

2,求一條路徑上的點的點權和

3,對一條路徑進行輪換(假如路徑為a_1~a_k則a_1–>a_2,a_2–>a_3….a_k–>a_1)

容易想到用lct維護,輪換操作可以直接把左端點接到右端點的右兒子處,但這樣會改變樹的形態,具體實現就是把權值和形態分開來維護,維護樹的形態的lct中,每個splay的root記錄對應的權值splay的某乙個點(不一定是該splay的root,我們可以訪問的時候在跳到root,同時更新一下即可)

#include

#include

#include

#include

#define fo(i,a,b) for(i=a;i<=b;i++)

#define ll long long

#define l tree[x][0]

#define r tree[x][1]

using

namespace

std;

int w;char ch;

inline

int read()

const

int maxn=1e5+5;

int i,j,n,q[maxn],cnt,k[maxn],next[maxn*2],g[maxn*2],num,qs;

struct tsplay

void update(int x)

void ins(int x,int v)

void add(int x,int v)

void re(int x)

void clear(int x)

void chu(int x)

void rotate(int x)

void splay(int x)rotate(x);

}update(x);

}int root(int &x)

int kth(int &x,int k)

}void turn(int x)

}val;

struct tlct

void update(int x)

void ins(int x,int f,int v)

void re(int x)

void clear(int x)

void chu(int x)

void rotate(int x)

void splay(int x)rotate(x);

}update(x);

}void access(int x)

if (last)

val.update(x2),update(x);}}

void makeroot(int x)

void path(int x,int y)

}lct;

void add(int x,int y)

char c[10];

void pint(ll x)

void dfs(int x,int y)

}int main()else

if (c[1]=='q') pint(val.sum[ro]),putchar('\n');

else

if (x!=y)val.turn(ro);

}}

GDSOI2017 中學生資料結構題

第一行有乙個整數 n,表示 s 國城市的數量。接下來有 n 1 行,每行兩個數 u,v 表示一條道路。第 n 1 行為乙個整數 q,表示接下來有 q 個操作。接下來有 q 行,每行表示乙個操作,格式如題目描述所示。對於每乙個 query 操作,輸出乙個數,表示詢問的當前編號為 x 和編號為 y 的城...

GDSOI2017 中學生資料結構題(LCT)

雖然這只是sone0裡很小的一部分,但是我認為這是最煩的一部分,對著乙個錯誤的題目調了兩天tat 最後才發現自己的程式的輪換打反了 如果想直接用一棵lct來做有乙個最簡單的想法,就是把x到y這段提取出來,然後再輪換一下。但是,這個想法明顯有問題,因為輪換的時候只是換了一下相對順序,並沒有交換權值的大...

GDSOI2017 中學生資料結構題 Lct練習

給出一棵樹。要求維護 一條路徑上的點權和。修改1 一條路徑上的點的點權全部加上乙個數。修改2 shift 假設乙個路徑上的點是ax,ak1,ak2,ay 就把ax的點權放到ak1上,把ak1的點權放到ak2上,把ay的點權放到ax上。我連去soi的資格都沒有 當時去聽講,不會splay,不會lct,...