9.27T3 左偏树/可并堆

                                                                 3.攻城4591
                                                                  (attack)

【问题描述】

小铭铭最近获得了一副新的桌游,游戏中需要用m个骑士攻占n个城池。
  这n个城池用1到n的整数表示。除1号城池外,城池i会受到另一座城池fi的管辖,其中fi<i。也就是说,所有城池构成了一棵有根树。这m个骑士用1到m的整数表示,其中第i个骑士的初始战斗力为si,第一个攻击的城池为ci。
  每个城池有一个防御值hi,如果一个骑士的战斗力大于等于城池的生命值,那么骑士就可以占领这座城池;否则占领失败,骑士将在这座城池牺牲。占领一个城池以后,骑士的战斗力将发生变化,然后继续攻击管辖这座城池的城池,直到占领1号城池,或牺牲为止。
  除1号城池外,每个城池i会给出一个战斗力变化参数ai,vi。若ai=0,攻占城池i以后骑士战斗力会增加vi;若ai=1,攻占城池i以后,战斗力会乘以vi。
  注意每个骑士是单独计算的。也就是说一个骑士攻击一座城池,不管结果如何,均不会影响其他骑士攻击这座城池的结果。
  现在的问题是,对于每个城池,输出有多少个骑士在这里牺牲;对于每个骑士,输出他攻占的城池数量。

【输入】

  第1行包含两个正整数n,m,表示城池的数量和骑士的数量。
  第2行包含n个整数,其中第i个数为hi,表示城池i的防御值。
  第3到n+1行,每行包含三个整数。其中第i+1行的三个数为fi,ai,vi,分别表示管辖这座城池的城池编号和两个战斗力变化参数。
  第n+2到n+m+1行,每行包含两个整数。其中第n+i行的两个数为si,ci,分别表示初始战斗力和第一个攻击的城池。

【输出】

  输出n+m行,每行包含一个非负整数。其中前n行分别表示在城池1到n牺牲的骑士数量,后m行分别表示骑士1到m攻占的城池数量。

【样例输入】

5 5

50 20 10 10 30

1 1 2

2 0 5

2 0 -10

1 0 10

20 2

10 3

40 4

20 4

35 5

【样例输出】

2

2

0

0

0

1

1

3

1

1

【数据范围】
  对于20%的数据,0 < n,m <= 3000;
  对于20%的数据,保证对于所有的城池i,fi=i-1。
  对于20%的数据,保证对于所有的城池i,ai=0,vi=0。
  以上三类数据两两没有交集。
  对于100%的数据,1<=n,m<=300000,1<=fi<i,1<=ci<=n,-10^18<=hi,vi,si<=10^18,ai{0,1}
;当ai=1时,vi>0;保证任何时候骑士战斗力值的绝对值不超过10^18。

 

 

首先我们来欣赏一下LZY大神的代码;

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 using namespace std;
  7 namespace fastIO{
  8     #define BUF_SIZE 100000
  9     #define OUT_SIZE 100000
 10     #define ll long long
 11     //fread->read
 12     bool IOerror=0;
 13     inline char nc(){
 14         static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
 15         if (p1==pend){
 16             p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
 17             if (pend==p1){IOerror=1;return -1;}
 18             //{printf("IO error!\n");system("pause");for (;;);exit(0);}
 19         }
 20         return *p1++;
 21     }
 22     inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
 23     inline void read(int &x){
 24         bool sign=0; char ch=nc(); x=0;
 25         for (;blank(ch);ch=nc());
 26         if (IOerror)return;
 27         if (ch=='-')sign=1,ch=nc();
 28         for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
 29         if (sign)x=-x;
 30     }
 31     inline void read(ll &x){
 32         bool sign=0; char ch=nc(); x=0;
 33         for (;blank(ch);ch=nc());
 34         if (IOerror)return;
 35         if (ch=='-')sign=1,ch=nc();
 36         for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
 37         if (sign)x=-x;
 38     }
 39     inline void read(double &x){
 40         bool sign=0; char ch=nc(); x=0;
 41         for (;blank(ch);ch=nc());
 42         if (IOerror)return;
 43         if (ch=='-')sign=1,ch=nc();
 44         for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
 45         if (ch=='.'){
 46             double tmp=1; ch=nc();
 47             for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
 48         }
 49         if (sign)x=-x;
 50     }
 51     inline void read(char *s){
 52         char ch=nc();
 53         for (;blank(ch);ch=nc());
 54         if (IOerror)return;
 55         for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
 56         *s=0;
 57     }
 58     inline void read(char &c){
 59         for (c=nc();blank(c);c=nc());
 60         if (IOerror){c=-1;return;}
 61     }
 62     //getchar->read
 63     inline void read1(int &x){
 64         char ch;int bo=0;x=0;
 65         for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
 66         for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
 67         if (bo)x=-x;
 68     }
 69     inline void read1(ll &x){
 70         char ch;int bo=0;x=0;
 71         for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
 72         for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
 73         if (bo)x=-x;
 74     }
 75     inline void read1(double &x){
 76         char ch;int bo=0;x=0;
 77         for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
 78         for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
 79         if (ch=='.'){
 80             double tmp=1;
 81             for (ch=getchar();ch>='0'&&ch<='9';tmp/=10.0,x+=tmp*(ch-'0'),ch=getchar());
 82         }
 83         if (bo)x=-x;
 84     }
 85     inline void read1(char *s){
 86         char ch=getchar();
 87         for (;blank(ch);ch=getchar());
 88         for (;!blank(ch);ch=getchar())*s++=ch;
 89         *s=0;
 90     }
 91     inline void read1(char &c){for (c=getchar();blank(c);c=getchar());}
 92     //scanf->read
 93     inline void read2(int &x){scanf("%d",&x);}
 94     inline void read2(ll &x){
 95         #ifdef _WIN32
 96             scanf("%I64d",&x);
 97         #else
 98         #ifdef __linux
 99             scanf("%lld",&x);
100         #else
101             puts("error:can't recognize the system!");
102         #endif
103         #endif
104     }
105     inline void read2(double &x){scanf("%lf",&x);}
106     inline void read2(char *s){scanf("%s",s);}
107     inline void read2(char &c){scanf(" %c",&c);}
108     inline void readln2(char *s){gets(s);}
109     //fwrite->write
110     struct Ostream_fwrite{
111         char *buf,*p1,*pend;
112         Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
113         void out(char ch){
114             if (p1==pend){
115                 fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
116             }
117             *p1++=ch;
118         }
119         void print(int x){
120             static char s[15],*s1;s1=s;
121             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
122             while(x)*s1++=x%10+'0',x/=10;
123             while(s1--!=s)out(*s1);
124         }
125         void println(int x){
126             static char s[15],*s1;s1=s;
127             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
128             while(x)*s1++=x%10+'0',x/=10;
129             while(s1--!=s)out(*s1); out('\n');
130         }
131         void print(ll x){
132             static char s[25],*s1;s1=s;
133             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
134             while(x)*s1++=x%10+'0',x/=10;
135             while(s1--!=s)out(*s1);
136         }
137         void println(ll x){
138             static char s[25],*s1;s1=s;
139             if (!x)*s1++='0';if (x<0)out('-'),x=-x;
140             while(x)*s1++=x%10+'0',x/=10;
141             while(s1--!=s)out(*s1); out('\n');
142         }
143         void print(double x,int y){
144             static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
145                 1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
146                 100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
147             if (x<-1e-12)out('-'),x=-x;x*=mul[y];
148             ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
149             ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
150             if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
151         }
152         void println(double x,int y){print(x,y);out('\n');}
153         void print(char *s){while (*s)out(*s++);}
154         void println(char *s){while (*s)out(*s++);out('\n');}
155         void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
156         ~Ostream_fwrite(){flush();}
157     }Ostream;
158     inline void print(int x){Ostream.print(x);}
159     inline void println(int x){Ostream.println(x);}
160     inline void print(char x){Ostream.out(x);}
161     inline void println(char x){Ostream.out(x);Ostream.out('\n');}
162     inline void print(ll x){Ostream.print(x);}
163     inline void println(ll x){Ostream.println(x);}
164     inline void print(double x,int y){Ostream.print(x,y);}
165     inline void println(double x,int y){Ostream.println(x,y);}
166     inline void print(char *s){Ostream.print(s);}
167     inline void println(char *s){Ostream.println(s);}
168     inline void println(){Ostream.out('\n');}
169     inline void flush(){Ostream.flush();}
170     //puts->write
171     char Out[OUT_SIZE],*o=Out;
172     inline void print1(int x){
173         static char buf[15];
174         char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
175         while(x)*p1++=x%10+'0',x/=10;
176         while(p1--!=buf)*o++=*p1;
177     }
178     inline void println1(int x){print1(x);*o++='\n';}
179     inline void print1(ll x){
180         static char buf[25];
181         char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
182         while(x)*p1++=x%10+'0',x/=10;
183         while(p1--!=buf)*o++=*p1;
184     }
185     inline void println1(ll x){print1(x);*o++='\n';}
186     inline void print1(char c){*o++=c;}
187     inline void println1(char c){*o++=c;*o++='\n';}
188     inline void print1(char *s){while (*s)*o++=*s++;}
189     inline void println1(char *s){print1(s);*o++='\n';}
190     inline void println1(){*o++='\n';}
191     inline void flush1(){if (o!=Out){if (*(o-1)=='\n')*--o=0;puts(Out);}}
192     struct puts_write{
193         ~puts_write(){flush1();}
194     }_puts;
195     inline void print2(int x){printf("%d",x);}
196     inline void println2(int x){printf("%d\n",x);}
197     inline void print2(char x){printf("%c",x);}
198     inline void println2(char x){printf("%c\n",x);}
199     inline void print2(ll x){
200         #ifdef _WIN32
201             printf("%I64d",x);
202         #else
203         #ifdef __linux
204             printf("%lld",x);
205         #else
206             puts("error:can't recognize the system!");
207         #endif
208         #endif
209     }
210     inline void println2(ll x){print2(x);printf("\n");}
211     inline void println2(){printf("\n");}
212     #undef ll
213     #undef OUT_SIZE
214     #undef BUF_SIZE
215 };
216 using namespace fastIO;
217 
218 typedef int INT;
219 #define int long long
220 const int N=1e6+10;
221 struct Left_List_Tree{
222     struct Front_star{
223         int u,v,nxt;
224     }e[N<<1];
225     int cnt;
226     int first[N];
227     void add(int u,int v){
228         ++cnt;
229         e[cnt].u=u;
230         e[cnt].v=v;
231         e[cnt].nxt=first[u];
232         first[u]=cnt;
233     }
234     //
235     int root[N];
236     int lson[N];
237     int rson[N];
238     int dis[N];
239     int siz[N];
240     //
241     int addlazy[N];
242     int mullazy[N];
243     int s[N];//the sum of the heap
244     //
245     int val[N];
246     int mul[N];
247     int c[N];
248     //
249     int h[N];
250     int Die[N];
251     int Win[N];
252     int dep[N];
253     //
254     int n,m;
255     //
256     inline void PushNow(int p,int mul,int add){
257         if(!p)return;
258         if(mul){
259             s[p]*=mul;
260             mullazy[p]*=mul;
261         }
262 //        cout<<s[p]<<" ";
263         s[p]+=add;
264 //        cout<<s[p]<<" sp "<<'\n';
265         addlazy[p]*=mul;
266         addlazy[p]+=add;
267     }
268     inline void PushDown(int p){
269 //        cout<<"down"<<p<<'\n';
270         PushNow(lson[p],mullazy[p],addlazy[p]);
271         PushNow(rson[p],mullazy[p],addlazy[p]);
272         addlazy[p]=0;
273         mullazy[p]=1;
274     }
275     inline int Merge(int A,int B){
276         if(!A||!B)return A+B;
277         PushDown(A);
278         PushDown(B);
279         if(s[A]>s[B]){
280             swap(A,B);
281         }
282         rson[A]=Merge(rson[A],B);
283         if(dis[lson[A]]<dis[rson[A]])swap(lson[A],rson[A]);
284         dis[A]=dis[rson[A]]+1;
285         return A;
286     }
287     inline void DFS(int u){
288         for(int i=first[u];i;i=e[i].nxt){
289             int v=e[i].v;
290             dep[v]=dep[u]+1;
291             DFS(v);
292             root[u]=Merge(root[u],root[v]);
293         }
294         while(root[u]&&s[root[u]]<h[u]){
295 //            cout<<u<<" "<<root[u]<<" "<<s[root[u]]<<" "<<h[u]<<'\n';
296             PushDown(root[u]);
297             ++Die[u];
298             Win[root[u]]=dep[c[root[u]]]-dep[u];
299             root[u]=Merge(lson[root[u]],rson[root[u]]);
300         }
301 //        if(u==4)
302         if(mul[u]==0)PushNow(root[u],1,val[u]);
303         else PushNow(root[u],val[u],0);
304 //        if(u==4){
305 //            while(root[u]){
306 //                cout<<u<<" "<<root[u]<<" "<<s[root[u]]<<" "<<h[u]<<'\n';
307 //                root[u]=Merge(lson[root[u]],rson[root[u]]);
308 //            }            
309 //            exit(0);
310 //        }
311     }
312     void Input(){
313         read(n);
314         read(m);
315         for(int i=1;i<=n;++i)read(h[i]);
316         for(int i=2;i<=n;++i){
317             int fa,opt,v;
318             read(fa);
319             read(opt);
320             read(v);
321             add(fa,i);
322             mul[i]=opt;
323             val[i]=v;
324         }
325         for(int i=1;i<=m;++i){
326             read(s[i]);
327             read(c[i]);
328             mullazy[i]=1;
329             root[c[i]]=Merge(root[c[i]],i);
330         }
331         dep[1]=1;
332         DFS(1);
333         while(root[1]){
334             PushDown(root[1]);
335             Win[root[1]]=dep[c[root[1]]];
336             root[1]=Merge(lson[root[1]],rson[root[1]]);
337         }
338     }
339     void OutPut(){
340         for(int i=1;i<=n;++i){
341             cout<<Die[i]<<'\n';
342         }
343         for(int i=1;i<=m;++i){
344             cout<<Win[i]<<'\n';
345         }
346     }
347 }Solution;
348 INT main(){
349     freopen("attack.in","r",stdin);
350     freopen("attack.out","w",stdout);
351     Solution.Input();
352     Solution.OutPut();
353     return 0;
354 }

 

posted @ 2018-09-27 19:57  saionjisekai  阅读(47)  评论(0编辑  收藏  举报