和Leo一起做爱树上结构的好孩子JLOI2015攻击游戏

版权声明:LeoJAM Presents https://blog.csdn.net/fcb_x/article/details/82874589

小铭铭最近获得了一副新的桌游,游戏中需要用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。
  注意每个骑士是单独计算的。也就是说一个骑士攻击一座城池,不管结果如何,均不会影响其他骑士攻击这座城池的结果。
  现在的问题是,对于每个城池,输出有多少个骑士在这里牺牲;对于每个骑士,输出他攻占的城池数量。

树上维护权值,存在加和乘的两个操作

考虑两个lazy

然后发现需要维护一个可以合并的结构:比如左偏树(配对堆写挂了

注意删除的时候要PushDown(我忘了调了好久

毒瘤加了一个FastIO

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
namespace fastIO{
    #define BUF_SIZE 100000
    #define OUT_SIZE 100000
    #define ll long long
    //fread->read
    bool IOerror=0;
    inline char nc(){
        static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
        if (p1==pend){
            p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
            if (pend==p1){IOerror=1;return -1;}
            //{printf("IO error!\n");system("pause");for (;;);exit(0);}
        }
        return *p1++;
    }
    inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
    inline void read(int &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (sign)x=-x;
    }
    inline void read(ll &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (sign)x=-x;
    }
    inline void read(double &x){
        bool sign=0; char ch=nc(); x=0;
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        if (ch=='-')sign=1,ch=nc();
        for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
        if (ch=='.'){
            double tmp=1; ch=nc();
            for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
        }
        if (sign)x=-x;
    }
    inline void read(char *s){
        char ch=nc();
        for (;blank(ch);ch=nc());
        if (IOerror)return;
        for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
        *s=0;
    }
    inline void read(char &c){
        for (c=nc();blank(c);c=nc());
        if (IOerror){c=-1;return;}
    }
    //getchar->read
    inline void read1(int &x){
        char ch;int bo=0;x=0;
        for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
        for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
        if (bo)x=-x;
    }
    inline void read1(ll &x){
        char ch;int bo=0;x=0;
        for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
        for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
        if (bo)x=-x;
    }
    inline void read1(double &x){
        char ch;int bo=0;x=0;
        for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
        for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
        if (ch=='.'){
            double tmp=1;
            for (ch=getchar();ch>='0'&&ch<='9';tmp/=10.0,x+=tmp*(ch-'0'),ch=getchar());
        }
        if (bo)x=-x;
    }
    inline void read1(char *s){
        char ch=getchar();
        for (;blank(ch);ch=getchar());
        for (;!blank(ch);ch=getchar())*s++=ch;
        *s=0;
    }
    inline void read1(char &c){for (c=getchar();blank(c);c=getchar());}
    //scanf->read
    inline void read2(int &x){scanf("%d",&x);}
    inline void read2(ll &x){
        #ifdef _WIN32
            scanf("%I64d",&x);
        #else
        #ifdef __linux
            scanf("%lld",&x);
        #else
            puts("error:can't recognize the system!");
        #endif
        #endif
    }
    inline void read2(double &x){scanf("%lf",&x);}
    inline void read2(char *s){scanf("%s",s);}
    inline void read2(char &c){scanf(" %c",&c);}
    inline void readln2(char *s){gets(s);}
    //fwrite->write
    struct Ostream_fwrite{
        char *buf,*p1,*pend;
        Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
        void out(char ch){
            if (p1==pend){
                fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
            }
            *p1++=ch;
        }
        void print(int x){
            static char s[15],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1);
        }
        void println(int x){
            static char s[15],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1); out('\n');
        }
        void print(ll x){
            static char s[25],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1);
        }
        void println(ll x){
            static char s[25],*s1;s1=s;
            if (!x)*s1++='0';if (x<0)out('-'),x=-x;
            while(x)*s1++=x%10+'0',x/=10;
            while(s1--!=s)out(*s1); out('\n');
        }
        void print(double x,int y){
            static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
                1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
                100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
            if (x<-1e-12)out('-'),x=-x;x*=mul[y];
            ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
            ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
            if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
        }
        void println(double x,int y){print(x,y);out('\n');}
        void print(char *s){while (*s)out(*s++);}
        void println(char *s){while (*s)out(*s++);out('\n');}
        void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
        ~Ostream_fwrite(){flush();}
    }Ostream;
    inline void print(int x){Ostream.print(x);}
    inline void println(int x){Ostream.println(x);}
    inline void print(char x){Ostream.out(x);}
    inline void println(char x){Ostream.out(x);Ostream.out('\n');}
    inline void print(ll x){Ostream.print(x);}
    inline void println(ll x){Ostream.println(x);}
    inline void print(double x,int y){Ostream.print(x,y);}
    inline void println(double x,int y){Ostream.println(x,y);}
    inline void print(char *s){Ostream.print(s);}
    inline void println(char *s){Ostream.println(s);}
    inline void println(){Ostream.out('\n');}
    inline void flush(){Ostream.flush();}
    //puts->write
    char Out[OUT_SIZE],*o=Out;
    inline void print1(int x){
        static char buf[15];
        char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
        while(x)*p1++=x%10+'0',x/=10;
        while(p1--!=buf)*o++=*p1;
    }
    inline void println1(int x){print1(x);*o++='\n';}
    inline void print1(ll x){
        static char buf[25];
        char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
        while(x)*p1++=x%10+'0',x/=10;
        while(p1--!=buf)*o++=*p1;
    }
    inline void println1(ll x){print1(x);*o++='\n';}
    inline void print1(char c){*o++=c;}
    inline void println1(char c){*o++=c;*o++='\n';}
    inline void print1(char *s){while (*s)*o++=*s++;}
    inline void println1(char *s){print1(s);*o++='\n';}
    inline void println1(){*o++='\n';}
    inline void flush1(){if (o!=Out){if (*(o-1)=='\n')*--o=0;puts(Out);}}
    struct puts_write{
        ~puts_write(){flush1();}
    }_puts;
    inline void print2(int x){printf("%d",x);}
    inline void println2(int x){printf("%d\n",x);}
    inline void print2(char x){printf("%c",x);}
    inline void println2(char x){printf("%c\n",x);}
    inline void print2(ll x){
        #ifdef _WIN32
            printf("%I64d",x);
        #else
        #ifdef __linux
            printf("%lld",x);
        #else
            puts("error:can't recognize the system!");
        #endif
        #endif
    }
    inline void println2(ll x){print2(x);printf("\n");}
    inline void println2(){printf("\n");}
    #undef ll
    #undef OUT_SIZE
    #undef BUF_SIZE
};
using namespace fastIO;

typedef int INT;
#define int long long
const int N=1e6+10;
struct Left_List_Tree{
	struct Front_star{
		int u,v,nxt;
	}e[N<<1];
	int cnt;
	int first[N];
	void add(int u,int v){
		++cnt;
		e[cnt].u=u;
		e[cnt].v=v;
		e[cnt].nxt=first[u];
		first[u]=cnt;
	}
	//
	int root[N];
	int lson[N];
	int rson[N];
	int dis[N];
	int siz[N];
	//
	int addlazy[N];
	int mullazy[N];
	int s[N];//the sum of the heap
	//
	int val[N];
	int mul[N];
	int c[N];
	//
	int h[N];
	int Die[N];
	int Win[N];
	int dep[N];
	//
	int n,m;
	//
	inline void PushNow(int p,int mul,int add){
		if(!p)return;
		if(mul){
			s[p]*=mul;
			mullazy[p]*=mul;
		}
//		cout<<s[p]<<" ";
		s[p]+=add;
//		cout<<s[p]<<" sp "<<'\n';
		addlazy[p]*=mul;
		addlazy[p]+=add;
	}
	inline void PushDown(int p){
//		cout<<"down"<<p<<'\n';
		PushNow(lson[p],mullazy[p],addlazy[p]);
		PushNow(rson[p],mullazy[p],addlazy[p]);
		addlazy[p]=0;
		mullazy[p]=1;
	}
	inline int Merge(int A,int B){
		if(!A||!B)return A+B;
		PushDown(A);
		PushDown(B);
		if(s[A]>s[B]){
			swap(A,B);
		}
		rson[A]=Merge(rson[A],B);
		if(dis[lson[A]]<dis[rson[A]])swap(lson[A],rson[A]);
		dis[A]=dis[rson[A]]+1;
		return A;
	}
	inline void DFS(int u){
		for(int i=first[u];i;i=e[i].nxt){
			int v=e[i].v;
			dep[v]=dep[u]+1;
			DFS(v);
			root[u]=Merge(root[u],root[v]);
		}
		while(root[u]&&s[root[u]]<h[u]){
//			cout<<u<<" "<<root[u]<<" "<<s[root[u]]<<" "<<h[u]<<'\n';
			PushDown(root[u]);
			++Die[u];
			Win[root[u]]=dep[c[root[u]]]-dep[u];
			root[u]=Merge(lson[root[u]],rson[root[u]]);
		}
//		if(u==4)
		if(mul[u]==0)PushNow(root[u],1,val[u]);
		else PushNow(root[u],val[u],0);
//		if(u==4){
//			while(root[u]){
//				cout<<u<<" "<<root[u]<<" "<<s[root[u]]<<" "<<h[u]<<'\n';
//				root[u]=Merge(lson[root[u]],rson[root[u]]);
//			}			
//			exit(0);
//		}
	}
	void Input(){
		read(n);
		read(m);
		for(int i=1;i<=n;++i)read(h[i]);
		for(int i=2;i<=n;++i){
			int fa,opt,v;
			read(fa);
			read(opt);
			read(v);
			add(fa,i);
			mul[i]=opt;
			val[i]=v;
		}
		for(int i=1;i<=m;++i){
			read(s[i]);
			read(c[i]);
			mullazy[i]=1;
			root[c[i]]=Merge(root[c[i]],i);
		}
		dep[1]=1;
		DFS(1);
		while(root[1]){
			PushDown(root[1]);
			Win[root[1]]=dep[c[root[1]]];
			root[1]=Merge(lson[root[1]],rson[root[1]]);
		}
	}
	void OutPut(){
		for(int i=1;i<=n;++i){
			cout<<Die[i]<<'\n';
		}
		for(int i=1;i<=m;++i){
			cout<<Win[i]<<'\n';
		}
	}
}Solution;
INT main(){
	freopen("attack.in","r",stdin);
	freopen("attack.out","w",stdout);
	Solution.Input();
	Solution.OutPut();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/fcb_x/article/details/82874589