标签:include date 表示 com mem 自己 sort 区间 pen
http://www.cnblogs.com/duoxiao/p/5777644.html 官方题解在这里
其实这道题不难,当初训练的时候不会做说明自己太弱
lazy标记不pushdown就是用lazy表示这个区间整体有哪些加减操作(大区间答案正确,子区间答案需要被所有祖先区间的lazy修正)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 struct way{int po,next;} e[100010]; 5 struct node{int laz,l,r,s,mx,mi;} tr[60010*50]; 6 struct qst{int l,r;} q[200010]; 7 int l[50010],r[50010],a[200010],fa[50010],c[50010],d[50010],p[50010],h[50010]; 8 int n,len,t,op,ans,qq,m; 9 10 bool cmp(int a,int b) 11 { 12 if (l[a]==l[b]) return r[a]<r[b]; 13 return l[a]<l[b]; 14 } 15 16 void add(int x,int y) 17 { 18 e[++len].po=y; 19 e[len].next=p[x]; 20 p[x]=len; 21 } 22 23 void dfs(int x) 24 { 25 l[x]=++t; c[t]=x; 26 for (int i=p[x]; i; i=e[i].next) 27 { 28 int y=e[i].po; 29 if (fa[x]!=y) 30 { 31 d[y]=d[x]+1; 32 fa[y]=x; 33 dfs(y); 34 } 35 } 36 r[x]=t; 37 } 38 39 void update(int i,int sz) 40 { 41 int l=tr[i].l, r=tr[i].r; 42 tr[i].s=tr[l].s+tr[r].s+tr[i].laz*sz; 43 tr[i].mx=max(tr[l].mx,tr[r].mx)+tr[i].laz; 44 tr[i].mi=min(tr[l].mi,tr[r].mi)+tr[i].laz; 45 } 46 47 int build(int l,int r) 48 { 49 tr[++t].laz=0; 50 if (l==r) 51 { 52 tr[t].mx=tr[t].mi=tr[t].s=d[c[l]]; 53 return t; 54 } 55 int m=(l+r)>>1,q=t; 56 tr[q].l=build(l,m); 57 tr[q].r=build(m+1,r); 58 update(q,r-l+1); 59 return q; 60 } 61 62 void work(int i,int sz,int z) 63 { 64 tr[i].laz+=z; 65 tr[i].s+=z*sz; 66 tr[i].mx+=z; 67 tr[i].mi+=z; 68 } 69 70 int add(int last,int l,int r,int x,int y) 71 { 72 tr[++t]=tr[last]; 73 if (x<=l&&y>=r) 74 { 75 work(t,r-l+1,-2); 76 return t; 77 } 78 int m=(l+r)>>1,q=t; 79 if (x<=m) tr[q].l=add(tr[last].l,l,m,x,y); 80 if (y>m) tr[q].r=add(tr[last].r,m+1,r,x,y); 81 update(q,r-l+1); 82 return q; 83 } 84 85 void get(int x) 86 { 87 for (int i=p[x]; i; i=e[i].next) 88 { 89 int y=e[i].po; 90 if (fa[x]!=y) 91 { 92 h[y]=add(h[x],1,n,l[y],r[y]); 93 work(h[y],n,1); 94 get(y); 95 } 96 } 97 } 98 99 void ask(int q,int l,int r,int x,int y,int laz) 100 { 101 if (op==2&&laz+tr[q].mi>=ans) return; 102 if (op==3&&laz+tr[q].mx<=ans) return; 103 if (x<=l&&y>=r) 104 { 105 if (op==1) ans+=tr[q].s+(r-l+1)*laz; 106 else if (op==2) ans=min(ans,tr[q].mi+laz); 107 else if (op==3) ans=max(ans,tr[q].mx+laz); 108 return; 109 } 110 int m=(l+r)>>1; 111 if (x<=m) ask(tr[q].l,l,m,x,y,laz+tr[q].laz); 112 if (y>m) ask(tr[q].r,m+1,r,x,y,laz+tr[q].laz); 113 } 114 115 int main() 116 { 117 while (scanf("%d%d",&n,&qq)!=EOF) 118 { 119 len=0; memset(p,0,sizeof(p)); 120 for (int i=1; i<n; i++) 121 { 122 int x,y; 123 scanf("%d%d",&x,&y); 124 add(x,y); 125 add(y,x); 126 } 127 t=0; dfs(1); t=0; 128 h[1]=build(1,n); get(1); 129 ans=0; 130 while (qq--) 131 { 132 int k,x; bool ff=0; 133 scanf("%d%d%d",&k,&x,&op); 134 x=(x+ans)%n+1; 135 for (int i=1; i<=k; i++) scanf("%d",&a[i]); 136 if (op==1) ans=0; 137 else if (op==2) ans=1e9; 138 else ans=-1; 139 if (!k) {ff=1; ask(h[x],1,n,1,n,0);} 140 else { 141 sort(a+1,a+1+k,cmp); 142 q[m=1].l=l[a[1]]; q[1].r=r[a[1]]; 143 for (int i=2; i<=k; i++) 144 if (l[a[i]]>q[m].r) 145 { 146 q[++m].l=l[a[i]]; 147 q[m].r=r[a[i]]; 148 } 149 else q[m].r=max(q[m].r,r[a[i]]); 150 q[m+1].l=n+1; 151 int st=1, en=q[1].l-1; 152 for (int i=1; i<=m; i++) 153 { 154 if (st<=en) {ff=1; ask(h[x],1,n,st,en,0);} 155 st=q[i].r+1,en=q[i+1].l-1; 156 } 157 if (st<=en) {ff=1; ask(h[x],1,n,st,en,0);} 158 } 159 if (!ff) {puts("-1"); ans=0;} 160 else printf("%d\n",ans); 161 } 162 } 163 }
标签:include date 表示 com mem 自己 sort 区间 pen
原文地址:http://www.cnblogs.com/phile/p/6446072.html