日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P4592 [TJOI2018]异或

發布時間:2023/12/3 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P4592 [TJOI2018]异或 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

P4592 [TJOI2018]異或

題意:

現在有一顆以 1 為根節點的由 n 個節點組成的樹,節點從 1 至 n 編號。樹上每個節點上都有一個權值 vi。現在有 q 次操作,操作如下:
1 x z:查詢節點 x 的子樹中的節點權值與 z 異或結果的最大值。
2 x y z:查詢節點 x 到節點 y 的簡單路徑上的節點的權值與 z 異或結果最大值。

題解:

很明顯的可持久化01Trie
對于第一個問題,直接按照時間戳(DFS序)建立點權的可持久化01Trie,每次查詢就是對區間[dfn[u],dfn[u]+siz[u]-1]的詢問,(u的所有兒子都被包含在這個區間內)
關于第二個問題,我們都知道對于u->v的路徑,我們可以拆分成rt到u,rt到v,rt到lca,rt到fa[lca](老套路了)這四套路徑,建立rt到所有點的可持久化01Trie,然后查詢這四條路找到答案
相當于對于兩問建了兩個可持久化01Trie

代碼:

#include<bits/stdc++.h> #define debug(a,b) printf("%s = %d\n",a,b); using namespace std; typedef long long ll; typedef pair<int, int> PII; clock_t startTime, endTime; //Fe~Jozky const ll INF_ll=1e18; const int INF_int=0x3f3f3f3f; inline ll read(){ll s=0,w=1ll;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1ll;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10ll+((ch-'0')*1ll),ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w; } void rd_test(){#ifdef ONLINE_JUDGE#elsestartTime = clock(); //計時開始freopen("in.txt","r",stdin);#endif } void Time_test(){#ifdef ONLINE_JUDGE#elseendTime = clock(); //計時結束printf("\n運行時間為:%lfs\n",(double)(endTime - startTime) / CLOCKS_PER_SEC);#endif } int n,m,sum,dep[200001],a[200001],ktot,size[200001],tpos[200001],pre[200001],head[200001],tot,f[200001][25]; struct edge{int to,next; }g[1000001]; inline void made(int from,int to){g[++tot].to=to;g[tot].next=head[from];head[from]=tot; } struct Trie{int n,son[10000001][2],cnt=1,sum,root[200001],ct[10000001];void ins(int &rt,int x,int T){ct[++cnt]=ct[rt]+1;son[cnt][0]=son[rt][0];son[cnt][1]=son[rt][1];rt=cnt;if (T==-1) return;register bool y=(x>>T)&1;ins(son[rt][y],x,T-1);}inline void insert(int pre,int rt,int x){root[rt]=root[pre];ins(root[rt],x,30);}int QUE(int i,int j,int x,int T){//序列版if (T==-1) return 0;register bool y=(x>>T)&1;if (ct[son[j][1^y]]>ct[son[i][1^y]]) return ((1<<T)+QUE(son[i][1^y],son[j][1^y],x,T-1));else return QUE(son[i][y],son[j][y],x,T-1);}int queryxx(int i,int j,int lca,int fa,int x,int T){//樹上差分版if (T==-1) return 0;register bool y=(x>>T)&1;if (ct[son[j][1^y]]+ct[son[i][1^y]]>ct[son[lca][1^y]]+ct[son[fa][1^y]]) return ((1<<T)+queryxx(son[i][1^y],son[j][1^y],son[lca][1^y],son[fa][1^y],x,T-1));else return queryxx(son[i][y],son[j][y],son[lca][y],son[fa][y],x,T-1);}int queryx(int i,int j,int lc,int flc,int x,int T){return queryxx(root[i],root[j],root[lc],root[flc],x,T);}inline int query(int l,int r,int x){return QUE(root[l-1],root[r],x,30);} }tr1,tr2; void dfs0(int u,int fa){dep[u]=dep[fa]+1;f[u][0]=fa;tpos[u]=++ktot;pre[ktot]=u;tr1.insert(fa,u,a[u]);size[u]=1;for (int i=1;i<=21;i++) f[u][i]=f[f[u][i-1]][i-1];for (int i=head[u];i;i=g[i].next){int v=g[i].to;if (v==fa) continue;dfs0(v,u);size[u]+=size[v];} } inline int LCA(int x,int y){if (dep[x]<dep[y]) swap(x,y);for (int i=21;i>=0;i--){if (dep[f[x][i]]>=dep[y]) x=f[x][i];}if (x==y) return x;for (int i=21;i>=0;i--){if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];}return f[x][0]; } int main(){rd_test();n=read();m=read();for (int i=1;i<=n;i++) a[i]=read();for (int i=1;i<n;i++){int x=read(),y=read();made(x,y);made(y,x);}dfs0(1,0);for (int i=1;i<=n;i++){tr2.insert(i-1,i,a[pre[i]]);}while (m--){int opt=read();if (opt==1){int x=read(),y=read();printf("%d\n",tr2.query(tpos[x],tpos[x]+size[x]-1,y));}else{int x=read(),y=read(),z=read();int lca=LCA(x,y);printf("%d\n",tr1.queryx(x,y,lca,f[lca][0],z,30));}}Time_test(); }

寫的另一個還沒改完的代碼:

#include<bits/stdc++.h> #define debug(a,b) printf("%s = %d\n",a,b); using namespace std; typedef long long ll; typedef pair<int, int> PII; //Fe~Jozky clock_t startTime, endTime; const ll INF_ll=1e18; const int INF_int=0x3f3f3f3f; inline ll read(){ll s=0,w=1ll;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1ll;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10ll+((ch-'0')*1ll),ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w; } void rd_test(){#ifdef ONLINE_JUDGE#elsestartTime = clock(); //計時開始freopen("in.txt","r",stdin);#endif } void Time_test(){#ifdef ONLINE_JUDGE#elseendTime = clock(); //計時結束printf("\n運行時間為:%lfs\n",(double)(endTime - startTime) / CLOCKS_PER_SEC);#endif } const int maxn=3e5+9; vector<int>vec[maxn]; struct tree{int cnt=0;int ch[3]; }tr[maxn*40]; int rt[maxn]; int a[maxn]; int fa[maxn][25], dep[maxn], lg[maxn]; int rtnum=0; int dfn[maxn],predfn[maxn]; int dfnnum=0; int siz[maxn]; int newa[maxn]; void insert(int now,int pre,int x){for(int i=30;i>=0;i--){int c=((x>>i)&1);tr[now].ch[c^1]=tr[pre].ch[c^1];tr[now].ch[c]=++rtnum;now=tr[now].ch[c];pre=tr[pre].ch[c];tr[now].cnt=tr[pre].cnt+1;} } int query(int L,int R,int x){int sum=0;for(int i=30;i>=0;i--){int c=((x>>i)&1);if(tr[tr[R].ch[c^1]].cnt>tr[tr[L].ch[c^1]].cnt){sum+=(1<<i);L=tr[L].ch[c^1];R=tr[R].ch[c^1]; }else {L=tr[L].ch[c];R=tr[R].ch[c]; }}return sum; } void dfs(int now,int fath){siz[now]=1;dep[now]=dep[fath]+1;fa[now][0]=fath;for(int i=1;(1<<i)<=dep[now];i++)fa[now][i]=fa[fa[now][i-1]][i-1];dfn[now]=++dfnnum;newa[dfnnum]=a[now];//predfn[dfnnum]=now;for(int i=0;i<vec[now].size();i++){if(vec[now][i]!=fath){dfs(vec[now][i],now);siz[now]+=siz[vec[now][i]];}} } int LCA(int x,int y){if(dep[x]<dep[y])swap(x,y);while(dep[x]>dep[y])x=fa[x][lg[dep[x]]-dep[y]];if(x==y)return x;for(int i=lg[dep[x]];i>=0;i--){if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];}}return fa[x][0]; } int main() {rd_test(); int n,m;cin>>n>>m;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<n;i++){int u,v;cin>>u>>v;vec[u].push_back(v);vec[v].push_back(u);}lg[0]=-1;for(int i=1;i<=n;i++)lg[i]=lg[i>>1]+1;dfs(1,0);rt[0]=++rtnum;insert(rt[0],0,0);int tot=0;for(int i=1;i<=dfnnum;i++){tot^=newa[i];rt[i]=++rtnum;insert(rt[i],rt[i-1],tot);}for(int i=1;i<=m;i++){int op;scanf("%d",&op);int x,y,z;if(op==1){scanf("%d%d",&x,&z);int ans=query(rt[dfn[x]-1],rt[dfn[x]+siz[x]-1],z);printf("%d\n",ans);}else {scanf("%d%d%d",&x,&y,&z);if(dfn[x]>dfn[y])swap(x,y);int lca=LCA(x,y);//int ans=max(query(rt[dfn[lca]-1],rt[dfn[x]],z),query(rt[dfn[x]+siz[x]-1],rt[dfn[y]],z));cout<<"???"<<endl;}}Time_test(); }

總結

以上是生活随笔為你收集整理的P4592 [TJOI2018]异或的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。