hdu 4366 Successor http://acm.hdu.edu.cn/showproblem.php?pid=4366 2012-12-9
题意:给你一棵树,每个节点有能力值(abi)和忠诚值(val),询问一个节点,它的后代中能力值大于它,忠诚值最大的节点
遍历树,树状结构转换为线性结构,区间求max(val),abi>k,类似离线算法,先按abi排序,一个一个插入
View Code
1 #include <cstdio> 2 #include <vector> 3 #include <cstring> 4 #include <algorithm> 5 #include <map> 6 using namespace std; 7 8 const int N=50010<<2; 9 int tl[N],tr[N],val[N],abi[N],mv[N],p[N]; 10 int ans[N]; 11 vector<int> g[N]; 12 map<int,int> mp; 13 void dfs(int u,int &d) 14 { 15 tl[u]=d++; 16 for(int i=0;i<(int)g[u].size();i++) 17 dfs(g[u][i],d); 18 tr[u]=d; 19 } 20 bool cmp(int a,int b) 21 { 22 return abi[a]>abi[b] || (abi[a]==abi[b] && a<b); 23 } 24 void update(int p,int x,int rt,int l,int r) 25 { 26 if(l==r) {mv[rt]=x; return;} 27 int m=(l+r)>>1,lch=rt<<1,rch=lch|1; 28 if(p<=m) update(p,x,lch,l,m); 29 else update(p,x,rch,m+1,r); 30 mv[rt]=max(mv[lch],mv[rch]); 31 } 32 int query(int ql,int qr,int rt,int l,int r) 33 { 34 if(ql<=l && r<=qr) return mv[rt]; 35 int m=(l+r)>>1,lch=rt<<1,rch=lch|1; 36 int ans=-1; 37 if(ql<=m) ans=max(ans,query(ql,qr,lch,l,m)); 38 if(qr>m) ans=max(ans,query(ql,qr,rch,m+1,r)); 39 return ans; 40 } 41 int main() 42 { 43 int T; 44 scanf("%d",&T); 45 while(T--) 46 { 47 int n,m; 48 mp.clear(); mp[-1]=-1; 49 scanf("%d%d",&n,&m); 50 for(int i=0;i<n;i++) g[i].clear(); 51 for(int i=1;i<n;i++) 52 { 53 int fa; 54 scanf("%d%d%d",&fa,&val[i],&abi[i]); 55 g[fa].push_back(i); 56 mp[val[i]]=i; 57 p[i]=i; 58 } 59 int d=0; 60 dfs(0,d); 61 sort(p+1,p+n,cmp); 62 memset(mv,-1,sizeof(mv)); 63 for(int i=1;i<n;i++) 64 { 65 ans[p[i]]=query(tl[p[i]],tr[p[i]]-1,1,1,n-1); 66 update(tl[p[i]],val[p[i]],1,1,n-1); 67 } 68 ans[0]=-1; 69 for(int i=0;i<m;i++) 70 { 71 int q; 72 scanf("%d",&q); 73 printf("%d\n",mp[ans[q]]); 74 } 75 } 76 return 0; 77 }
hdu 4027 Can you answer these queries? http://acm.hdu.edu.cn/showproblem.php?pid=4027
题意:区间开根号,区间求和
线段树中整段区间的值都为1时,就不用更新了,否则暴力更新叶子节点,一个数开几次根号就会变为1
View Code
1 #include <cstdio> 2 #include <cmath> 3 using namespace std; 4 5 typedef long long LL; 6 const int N=100010<<4; 7 #define lch (rt<<1) 8 #define rch (rt<<1|1) 9 LL sum[N]; 10 void build(int rt,int l,int r) 11 { 12 if(l==r) 13 { 14 scanf("%I64d",&sum[rt]); 15 return; 16 } 17 int m=(l+r)/2; 18 build(lch,l,m); 19 build(rch,m+1,r); 20 sum[rt]=sum[lch]+sum[rch]; 21 } 22 void update(int ql,int qr,int rt,int l,int r) 23 { 24 if(sum[rt]==r-l+1) return; 25 if(l==r) 26 { 27 sum[rt]=(LL)(sqrt(sum[rt])+1e-8); 28 return; 29 } 30 int m=(l+r)/2; 31 if(ql<=m) update(ql,qr,lch,l,m); 32 if(qr>m) update(ql,qr,rch,m+1,r); 33 sum[rt]=sum[lch]+sum[rch]; 34 } 35 LL query(int ql,int qr,int rt,int l,int r) 36 { 37 if(ql<=l && r<=qr) return sum[rt]; 38 int m=(l+r)/2; 39 LL ans=0; 40 if(ql<=m) ans+=query(ql,qr,lch,l,m); 41 if(qr>m) ans+=query(ql,qr,rch,m+1,r); 42 return ans; 43 } 44 int main() 45 { 46 int n,C=0; 47 while(~scanf("%d",&n)) 48 { 49 printf("Case #%d:\n",++C); 50 build(1,1,n); 51 int m; 52 scanf("%d",&m); 53 for(int i=0;i<m;i++) 54 { 55 int t,x,y; 56 scanf("%d%d%d",&t,&x,&y); 57 if(x>y) {int t=x; x=y; y=t;} 58 if(t==0) update(x,y,1,1,n); 59 else printf("%I64d\n",query(x,y,1,1,n)); 60 } 61 printf("\n"); 62 } 63 return 0; 64 }
hdu 3911 Black And White http://acm.hdu.edu.cn/showproblem.php?pid=4027
题意:01串,操作区间取反,求区间最长的连续1的长度
区间合并,s0最长的连续0的长度,ls0左端点开始最长连续0的长度,rs0一直右端点最长连续0的长度,s1,ls1,rs1类似,def延迟标记
View Code
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 const int N=100010<<2; 6 int s0[N],ls0[N],rs0[N],s1[N],ls1[N],rs1[N],def[N]; 7 void pushup(int rt,int l,int r) 8 { 9 int m=(l+r)>>1,lch=rt<<1,rch=lch|1; 10 11 s0[rt]=max(max(s0[lch],s0[rch]),rs0[lch]+ls0[rch]); 12 ls0[rt]=(ls0[lch]==m-l+1?ls0[lch]+ls0[rch]:ls0[lch]); 13 rs0[rt]=(rs0[rch]==r-m?rs0[rch]+rs0[lch]:rs0[rch]); 14 15 s1[rt]=max(max(s1[lch],s1[rch]),rs1[lch]+ls1[rch]); 16 ls1[rt]=(ls1[lch]==m-l+1?ls1[lch]+ls1[rch]:ls1[lch]); 17 rs1[rt]=(rs1[rch]==r-m?rs1[rch]+rs1[lch]:rs1[rch]); 18 } 19 void build(int rt,int l,int r) 20 { 21 def[rt]=0; 22 if(l==r) 23 { 24 int x; 25 scanf("%d",&x); 26 if(x==0) 27 { 28 s0[rt]=ls0[rt]=rs0[rt]=1; 29 s1[rt]=ls1[rt]=rs1[rt]=0; 30 } 31 else 32 { 33 s0[rt]=ls0[rt]=rs0[rt]=0; 34 s1[rt]=ls1[rt]=rs1[rt]=1; 35 } 36 return; 37 } 38 int m=(l+r)>>1,lch=rt<<1,rch=lch|1; 39 build(lch,l,m); 40 build(rch,m+1,r); 41 pushup(rt,l,r); 42 } 43 void pushdown(int rt) 44 { 45 if(def[rt]==0) return; 46 int lch=rt<<1,rch=lch|1; 47 48 swap(s0[lch],s1[lch]); 49 swap(ls0[lch],ls1[lch]); 50 swap(rs0[lch],rs1[lch]); 51 def[lch]^=1; 52 53 swap(s0[rch],s1[rch]); 54 swap(ls0[rch],ls1[rch]); 55 swap(rs0[rch],rs1[rch]); 56 def[rch]^=1; 57 58 def[rt]=0; 59 } 60 void update(int ql,int qr,int rt,int l,int r) 61 { 62 if(ql<=l && r<=qr) 63 { 64 swap(s0[rt],s1[rt]); 65 swap(ls0[rt],ls1[rt]); 66 swap(rs0[rt],rs1[rt]); 67 def[rt]^=1; 68 return; 69 } 70 pushdown(rt); 71 int m=(l+r)>>1,lch=rt<<1,rch=lch|1; 72 if(ql<=m) update(ql,qr,lch,l,m); 73 if(qr>m) update(ql,qr,rch,m+1,r); 74 pushup(rt,l,r); 75 } 76 int query(int ql,int qr,int rt,int l,int r) 77 { 78 if(ql<=l && r<=qr) return s1[rt]; 79 pushdown(rt); 80 int m=(l+r)>>1,lch=rt<<1,rch=lch|1; 81 int ans=0; 82 if(ql<=m) ans=max(ans,query(ql,qr,lch,l,m)); 83 if(qr>m) ans=max(ans,query(ql,qr,rch,m+1,r)); 84 if(ql<=m && m<qr) ans=max(ans,min(rs1[lch],m-ql+1)+min(ls1[rch],qr-m)); 85 return ans; 86 } 87 int main() 88 { 89 int n; 90 while(~scanf("%d",&n)) 91 { 92 build(1,1,n); 93 int m; 94 scanf("%d",&m); 95 for(int i=0;i<m;i++) 96 { 97 int x,l,r; 98 scanf("%d%d%d",&x,&l,&r); 99 if(x==1) update(l,r,1,1,n); 100 else printf("%d\n",query(l,r,1,1,n)); 101 } 102 } 103 return 0; 104 }