Short But Scary 解题报告
生活随笔
收集整理的這篇文章主要介紹了
Short But Scary 解题报告
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Short But Scary
正解的離線分治+虛樹(shù)的做法太神奇...搞不到
搞一個(gè)菜一點(diǎn)的ddp寫(xiě)寫(xiě),結(jié)果調(diào)了200年,下次一定寫(xiě)樹(shù)剖不寫(xiě)lct了,太難調(diào)了...
大概就是按sub2那樣維護(hù)
你每個(gè)重鏈開(kāi)一個(gè)線段樹(shù),然后鏈頭把貢獻(xiàn)扔給別的重鏈,然后每次在鏈上二分位置查一個(gè)和差不多了
然后可以拿lct寫(xiě)
但你得搞清楚翻轉(zhuǎn)的時(shí)候要翻轉(zhuǎn)的東西比較多,細(xì)節(jié)也比較多,異常的難寫(xiě)...
算了懶得說(shuō)了,給我毒瘤死了...
Code:
#include <cstdio> #include <cctype> #include <algorithm> #define ls ch[now][0] #define rs ch[now][1] #define fa par[now] const int N=1e5+10; template <class T> void read(T &x) {x=0;char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c)) x=x*10+c-'0',c=getchar(); } int head[N],to[N<<1],Next[N<<1],cnt; void add(int u,int v) {to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt; } int n,m; int ch[N][2],par[N],tag[N];//翻轉(zhuǎn)標(biāo)記 struct koito_yuu {int siz,is,lef,dat,si;//實(shí)際大小,子樹(shù)全是,最左邊的點(diǎn)是否是,與父親關(guān)系,虛兒子貢獻(xiàn) }yuu[2][N]; int s[N],tot; bool isroot(int now){return ch[fa][0]==now||ch[fa][1]==now;} int identity(int now){return ch[fa][1]==now;} void connect(int f,int now,int typ){ch[fa=f][typ]=now;} void Reverse(int now) {tag[now]^=1;std::swap(yuu[0][now],yuu[1][now]); } void updata(int now) {for(int k=0;k<=1;k++){yuu[k][now].is=(yuu[k][ls].is&&yuu[k][now].dat&&yuu[k][rs].is);yuu[k][now].siz=yuu[k][ls].siz;if(ls){yuu[k][now].lef=yuu[k][ls].lef;if(yuu[k][ls].is&&yuu[k][now].dat){yuu[k][now].siz+=yuu[k][now].si+1;if(yuu[k][rs].lef) yuu[k][now].siz+=yuu[k][rs].siz;}}else{yuu[k][now].lef=yuu[k][now].dat;yuu[k][now].siz+=yuu[k][now].si+1;if(yuu[k][rs].lef) yuu[k][now].siz+=yuu[k][rs].siz;}} } void pushdown(int now) {if(tag[now]){if(ls) Reverse(ls);if(rs) Reverse(rs);tag[now]=0;} } void Rotate(int now) {int p=fa,typ=identity(now);connect(p,ch[now][typ^1],typ);if(isroot(p)) connect(par[p],now,identity(p));else fa=par[p];connect(now,p,typ^1);updata(p);updata(now); } void splay(int now) {while(isroot(now)) s[++tot]=now,now=fa;s[++tot]=now;while(tot) pushdown(s[tot--]);now=s[1];for(;isroot(now);Rotate(now))if(isroot(fa))Rotate(identity(now)^identity(fa)?now:fa); } void access(int now) {for(int las=0;now;las=now,now=fa){splay(now);for(int k=0;k<=1;k++){if(yuu[0][rs].lef)yuu[k][now].si+=yuu[0][rs].siz;if(yuu[0][las].lef)yuu[k][now].si-=yuu[0][las].siz;}rs=las;updata(now);} } void dfs(int now,int f) {yuu[0][now].is=yuu[0][now].lef=yuu[0][now].dat=1;//yuu[1][now].is=yuu[1][now].lef=yuu[1][now].dat=1;for(int v,i=head[now];i;i=Next[i])if((v=to[i])!=f)par[v]=now,dfs(v,now),yuu[0][now].si+=yuu[0][v].siz;yuu[0][now].siz=yuu[0][now].si+1;yuu[1][now].si=yuu[0][now].si;yuu[1][now].siz=yuu[0][now].siz; } void modi(int u) {access(u);splay(u);Reverse(u); } int query(int now) {pushdown(now);if(!rs){if(yuu[0][now].dat&&ls) return query(ls)+yuu[0][now].si+1;return yuu[0][now].si+1;}if(yuu[0][rs].is){int ret=yuu[0][now].si+1+yuu[0][rs].siz;if(yuu[0][now].dat&&now!=1) ret+=query(ls);return ret;}return query(rs); } int qry(int u) {access(u);splay(u);return ((yuu[0][u].dat&&u!=1)?query(ch[u][0]):0)+yuu[0][u].si+1; } int main() {freopen("scary.in","r",stdin);freopen("scary.out","w",stdout);yuu[1][1].dat=yuu[0][0].is=yuu[1][0].is=1;read(n),read(m);for(int u,v,i=1;i<n;i++) read(u),read(v),add(u,v),add(v,u);dfs(1,0);for(int op,u,v,i=1;i<=m;i++){read(op);if(op==1){read(u),read(v);modi(u),modi(v);}else{read(u);printf("%d\n",qry(u));}}return 0; }2019.3.25
轉(zhuǎn)載于:https://www.cnblogs.com/butterflydew/p/10597011.html
總結(jié)
以上是生活随笔為你收集整理的Short But Scary 解题报告的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Aspose.word Java实现ht
- 下一篇: 视频录制——SurfaceView +