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 }