标题就很233的题目 数据结构滑稽题
在线算法:: 可并堆维护
太难写了 表示不爱
离线算法::带权并查集将操作离散到连续的区间上(超银河英雄传说 并查集基础训练题) 线段树处理之 比较simple
bzoj 2333
1 #include <bits/stdc++.h> 2 #define N 300010 3 using namespace std; 4 5 inline int read() 6 { 7 int x=0,f=1; 8 char ch=getchar(); 9 while(ch<'0'||ch>'9') 10 { 11 if(ch=='-')f=-1; 12 ch=getchar(); 13 } 14 while(ch>='0'&&ch<='9') 15 { 16 x=x*10+ch-'0'; 17 ch=getchar(); 18 } 19 return x*f; 20 } 21 struct query_struc 22 { 23 int tp,x,v; 24 int sf,sta; 25 } que[N]; 26 int tree[N<<2],tag[N<<2],A[N],vis[N]; 27 int n,q,fa[N],s[N],sz[N],pl[N],ks[N],S[N]; 28 int findfa(int x) 29 { 30 if(fa[x]==x) 31 return x; 32 int tt=findfa(fa[x]); 33 S[x]+=S[fa[x]]; 34 fa[x]=tt; 35 return fa[x]; 36 } 37 inline void pushup(int rt) 38 { 39 tree[rt]=max(tree[rt<<1],tree[rt<<1|1]); 40 } 41 inline void pushdown(int rt) 42 { 43 if(tag[rt]!=0) 44 { 45 tree[rt<<1]+=tag[rt]; 46 tree[rt<<1|1]+=tag[rt]; 47 tag[rt<<1]+=tag[rt]; 48 tag[rt<<1|1]+=tag[rt]; 49 tag[rt]=0; 50 } 51 } 52 void built(int l,int r,int rt) 53 { 54 if(l==r) 55 { 56 tree[rt]=A[pl[l]]; 57 return ; 58 } 59 int mid=(l+r)>>1; 60 built(l,mid,rt<<1); 61 built(mid+1,r,rt<<1|1); 62 pushup(rt); 63 } 64 void modify(int L,int R,int x,int l,int r,int rt) 65 { 66 if(L<=l&&r<=R) 67 { 68 tree[rt]+=x; 69 tag[rt]+=x; 70 return ; 71 } 72 int mid=(l+r)>>1; 73 pushdown(rt); 74 if(L<=mid) modify(L,R,x,l,mid,rt<<1); 75 if(R>mid) modify(L,R,x,mid+1,r,rt<<1|1); 76 pushup(rt); 77 } 78 int query(int L,int R,int l,int r,int rt) 79 { 80 if(L<=l&&r<=R) return tree[rt]; 81 int mid=(l+r)>>1,ans=-999999999; 82 pushdown(rt); 83 if(L<=mid) ans=max(ans,query(L,R,l,mid,rt<<1)); 84 if(R>mid ) ans=max(ans,query(L,R,mid+1,r,rt<<1|1)); 85 return ans; 86 } 87 int main() 88 { 89 // freopen("read.in","r",stdin); 90 // freopen("wro.out","w",stdout); 91 n=read(); 92 for(int i=1; i<=n; i++) fa[i]=i,sz[i]=1; 93 for(int i=1; i<=n; i++) A[i]=read(); 94 q=read(); 95 for(int i=1; i<=q; i++) 96 { 97 char ch[50]; 98 scanf("%s",ch); 99 if(ch[0]=='A') 100 { 101 que[i].tp=ch[1]-'0'; 102 if(ch[1]!='3') 103 { 104 que[i].x=read(); 105 que[i].v=read(); 106 que[i].sf=sz[findfa(que[i].x)]; 107 que[i].sta=fa[que[i].x]; 108 } 109 else que[i].v=read(); 110 } 111 if(ch[0]=='F') 112 { 113 que[i].tp=3+ch[1]-'0'; 114 if(ch[1]!='3') 115 { 116 que[i].x=read(); 117 que[i].sf=sz[findfa(que[i].x)]; 118 que[i].sta=fa[que[i].x]; 119 } 120 } 121 122 if(ch[0]=='U') 123 { 124 int x=read(),y=read(); 125 int f1=findfa(x),f2=findfa(y); 126 if(f1==f2) continue; 127 fa[f2]=f1; 128 S[f2]=sz[f1]; 129 sz[f1]+=sz[f2]; 130 } 131 } 132 int tot=0; 133 for(int i=1; i<=n; i++) 134 { 135 int x=findfa(i); 136 if(!vis[x]) 137 { 138 vis[x]=1; 139 ks[x]=tot; 140 tot+=sz[x]; 141 } 142 s[i]=S[i]+ks[x]; 143 } 144 for(int i=1; i<=n; i++) pl[s[i]+1]=i; 145 //check_print(); 146 built(1,n,1); 147 for(int i=1; i<=q; i++) 148 { 149 int x=que[i].x,v=que[i].v,sf=que[i].sf; 150 int sta=que[i].sta; 151 if(!que[i].tp) continue; 152 if(que[i].tp==1) 153 modify(s[x]+1,s[x]+1,v,1,n,1); 154 else if(que[i].tp==2) 155 modify(s[sta]+1,s[sta]+sf,v,1,n,1); 156 else if(que[i].tp==3) 157 modify(1,n,v,1,n,1); 158 else if(que[i].tp==4) 159 printf("%d\n",query(s[x]+1,s[x]+1,1,n,1)); 160 else if(que[i].tp==5) 161 printf("%d\n",query(s[sta]+1,s[sta]+sf,1,n,1)); 162 else printf("%d\n",tree[1]); 163 } 164 return 0; 165 }
ps: 原先wa了一发,但和黄学长的都拍上了 结果是建线段树初始权值没处理好 且dmk 偷懒初始值都赋成了0
因此 还是写的时候要仔细