bzoj 3531 旅行
动态开点线段树+树链剖分 对于每一种宗教信仰都开一颗线段树
空间: QlogN 即每一次修改都只会改变logN 个点
时间 O(QlogN) naive题 边没有开两倍 QAQ
bzoj 3531
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 inline int read() 5 { 6 int x=0,f=1; 7 char ch=getchar(); 8 while(ch<'0'||ch>'9') 9 { 10 if(ch=='-')f=-1; 11 ch=getchar(); 12 } 13 while(ch>='0'&&ch<='9') 14 { 15 x=x*10+ch-'0'; 16 ch=getchar(); 17 } 18 return x*f; 19 } 20 int ee=0,st[300010],fa[300010],top[300010],son[300010],lastadd; 21 int n,q,belif[300010],weight[300010],size[300010],dep[300010],cnt,pl[300010]; 22 struct edge 23 { 24 int v,next; 25 } vs[300010]; 26 inline void addedge(int u,int v) 27 { 28 vs[++ee].v=v; 29 vs[ee].next=st[u]; 30 st[u]=ee; 31 } 32 struct treenode 33 { 34 int l,r,mx,sum; 35 } tree[30000010]; 36 treenode operator+(treenode a,treenode b) 37 { 38 treenode tmp; 39 tmp.sum=a.sum+b.sum; 40 tmp.mx=max(a.mx,b.mx); 41 return tmp; 42 } 43 void modify(int q,int x,int l,int r,int rt) 44 { 45 if(l==r) 46 { 47 tree[rt].mx=x; 48 tree[rt].sum=x; 49 return ; 50 } 51 int mid=(l+r)>>1; 52 if(mid>=q) 53 { 54 if(!tree[rt].l) tree[rt].l=++cnt; 55 modify(q,x,l,mid,tree[rt].l); 56 } 57 if(mid<q) 58 { 59 if(!tree[rt].r) tree[rt].r=++cnt; 60 modify(q,x,mid+1,r,tree[rt].r); 61 } 62 tree[rt].sum=tree[tree[rt].l].sum+tree[tree[rt].r].sum; 63 tree[rt].mx=max(tree[tree[rt].l].mx,tree[tree[rt].r].mx); 64 } 65 treenode query(int L,int R,int l,int r,int rt) 66 { 67 if(L<=l&&r<=R) return tree[rt]; 68 int mid=(l+r)>>1; 69 if(mid>=R) return query(L,R,l,mid,tree[rt].l); 70 if(mid<L) return query(L,R,mid+1,r,tree[rt].r); 71 return query(L,R,l,mid,tree[rt].l)+query(L,R,mid+1,r,tree[rt].r); 72 } 73 void dfs1(int rt) 74 { 75 size[rt]=1; 76 for(int i=st[rt]; i; i=vs[i].next) 77 { 78 if(fa[rt]==vs[i].v) continue; 79 fa[vs[i].v]=rt; 80 dep[vs[i].v]=dep[rt]+1; 81 dfs1(vs[i].v); 82 size[rt]+=size[vs[i].v]; 83 if(size[son[rt]]<size[vs[i].v]) 84 son[rt]=vs[i].v; 85 } 86 } 87 void dfs2(int rt) 88 { 89 pl[rt]=++lastadd; 90 if(son[rt]) 91 { 92 top[son[rt]]=top[rt]; 93 dfs2(son[rt]); 94 } 95 for(int i=st[rt]; i; i=vs[i].next) 96 { 97 if(vs[i].v==fa[rt]||son[rt]==vs[i].v) continue; 98 dfs2(vs[i].v); 99 } 100 } 101 void op(int &a,treenode b,int tp) 102 { 103 if(tp==0) a=max(a,b.mx); 104 else a+=b.sum; 105 } 106 void calans(int x,int y,int tp) 107 { 108 int f1=top[x],f2=top[y]; 109 if(dep[f1]>dep[f2]) 110 swap(x,y),swap(f1,f2); 111 int ans=0,rt=belif[x]; 112 while(f1!=f2) 113 { 114 treenode tt=query(pl[f2],pl[y],1,n,rt); 115 op(ans,tt,tp); 116 y=fa[f2]; 117 f2=top[y]; 118 if(dep[f1]>dep[f2]) swap(f1,f2),swap(x,y); 119 } 120 if(dep[x]>dep[y]) swap(x,y); 121 treenode tt=query(pl[x],pl[y],1,n,rt); 122 op(ans,tt,tp); 123 printf("%d\n",ans); 124 } 125 void cgbelif(int x,int y) 126 { 127 modify(pl[x],0,1,n,belif[x]); 128 belif[x]=y; 129 modify(pl[x],weight[x],1,n,belif[x]); 130 } 131 void cgwight(int x,int y) 132 { 133 modify(pl[x],weight[x]=y,1,n,belif[x]); 134 } 135 int main() 136 { 137 cnt=100010; 138 n=read(); 139 q=read(); 140 for(int i=1; i<=n; i++) 141 top[i]=i; 142 for(int i=1; i<=n; i++) 143 { 144 weight[i]=read(); 145 belif[i]=read(); 146 } 147 for(int i=1; i<n; i++) 148 { 149 int a=read(),b=read(); 150 addedge(a,b); 151 addedge(b,a); 152 } 153 dfs1(1); 154 dfs2(1); 155 for(int i=1; i<=n; i++) 156 modify(pl[i],weight[i],1,n,belif[i]); 157 for(int i=1; i<=q; i++) 158 { 159 char sd[10]; 160 scanf("%s",sd); 161 int x=read(),y=read(); 162 if(sd[0]=='Q') 163 { 164 if(sd[1]=='M') calans(x,y,0); 165 else calans(x,y,1); 166 } 167 else if(sd[0]=='C') 168 { 169 if(sd[1]=='C') cgbelif(x,y); 170 else cgwight(x,y); 171 } 172 } 173 return 0; 174 }
蛤鸡附上 dmk
dmk_GG 好像有点问题QWQ
1 #include <bits/stdc++.h> 2 #define N 30010 3 #define Q 30010 4 #define C 1000 5 using namespace std; 6 7 int bf[N+10],wt[N+10],sign[N+10]; 8 vector <int> xx[N+10]; 9 char ch[4][3]= {{'Q','S','\0'},{'Q','S','\0'},{'C','C','\0'},{'C','W','\0'}}; 10 int main() 11 { 12 srand(time(0)); 13 freopen("read.in","w",stdout); 14 printf("%d %d\n",N,Q); 15 for(int i=1; i<=N; i++) 16 { 17 bf[i]=rand()%C+1; 18 xx[bf[i]].push_back(i); 19 wt[i]=rand()%10000; 20 } 21 for(int i=1; i<=N; i++) 22 printf("%d %d\n",wt[i],bf[i]); 23 sign[1]=1; 24 sign[2]=1; 25 printf("%d %d\n",1,2); 26 for(int i=1; i<N-1; i++) 27 { 28 int x=rand()%N+1,y=rand()%N+1; 29 while(!sign[x]) x=rand()%N+1; 30 while(sign[y]) y=rand()%N+1; 31 printf("%d %d\n",x,y); 32 sign[y]=1; 33 } 34 for(int i=1; i<=Q; i++) 35 { 36 int ty=rand()%4; 37 puts(ch[ty]); 38 if(ty==2||ty==3) 39 { 40 int x=rand()%N+1,y=rand()%C+1; 41 printf("%d %d\n",x,y); 42 if(ty==2) 43 { 44 for(int j=0; j<=(int)xx[bf[x]].size(); j++) 45 if(xx[bf[x]][j]==x) 46 xx[bf[x]].erase(xx[bf[x]].begin()+j); 47 bf[x]=y; 48 } 49 50 } 51 if(ty==0||ty==1) 52 { 53 int x=rand()%N+1; 54 while(xx[bf[x]].size()==1) 55 x=rand()%N+1; 56 printf("%d %d\n",x,xx[bf[x]][rand()%xx[bf[x]].size()]); 57 } 58 } 59 return 0; 60 }