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 }
View Code

 

posted on 2017-02-26 21:47  acphile  阅读(311)  评论(0编辑  收藏  举报