zoukankan      html  css  js  c++  java
  • 739B

    发现cf文本读确实变快了,但是用了快读树剖还是过不了2e5,好像常数大了4?

    后来才想起来这是离线的树链改值,差分就行了

    跪了的树剖:

    #include<bits/stdc++.h>  
    //#pragma comment(linker, "/STACK:1024000000,1024000000")   
    #include<stdio.h>  
    #include<algorithm>  
    #include<queue>  
    #include<string.h>  
    #include<iostream>  
    #include<math.h>                    
    #include<stack>
    #include<set>  
    #include<map>  
    #include<vector>  
    #include<iomanip> 
    #include<bitset>
    using namespace std;         //
    
    #define ll long long  
    #define ull unsigned long long
    #define pb push_back  
    #define FOR(a) for(int i=1;i<=a;i++) 
    #define sqr(a) (a)*(a)
    #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
    ll qp(ll a,ll b,ll mod){
    	ll t=1;while(b){if(b&1)t=t*a%mod;b>>=1;a=a*a%mod;}return t;
    }
    struct DOT{ll x;ll y;};
    //inline void read(int &x){int k=0;char f=1;char c=getchar();for(;!isdigit(c);c=getchar())if(c=='-')f=-1;for(;isdigit(c);c=getchar())k=k*10+c-'0';x=k*f;} 
    const int dx[4]={0,0,-1,1};
    const int dy[4]={1,-1,0,0};
    const int inf=0x3f3f3f3f; 
    const ll Linf=0x3f3f3f3f3f3f3f3f;
    const ll mod=1e9+7;;
    
    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!
    ");system("pause");for (;;);exit(0);}    
        }    
        return *p1++;    
    }    
    inline bool blank(char ch){return ch==' '||ch=='
    '||ch=='
    '||ch=='	';}    
    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;}    
    }   
    #undef OUT_SIZE    
    #undef BUF_SIZE    
    }; using namespace fastIO;  
    
    
    
    
    
    const int maxn=2e5+9;  
    
    int n;
     
    struct EDGE{
        int v;int w;int next;
    }G[maxn<<2];
    int head[maxn],tot;
    
    inline void addedge(int u,int v,int w){
        ++tot;G[tot].v=v;G[tot].next=head[u];G[tot].w=w;head[u]=tot;
    }
     
    int top[maxn];
    int pre[maxn];
    int dep[maxn];
    int num[maxn];	//子树尺寸
    int p[maxn];    //v的对应位置
    int out[maxn];  //退出时间戳
    int fp[maxn];   //访问序列
    int son[maxn];  //重儿子
    int pos;		//计时器
    
    inline void init(){
        memset(head,-1,sizeof head);tot=0;
    	memset(son,-1,sizeof son);
    }
    
    inline void dfs1(int u,int fa,int d){
        dep[u]=d;
        pre[u]=fa;
        num[u]=1;
        for(int i=head[u];~i;i=G[i].next){
            int v=G[i].v;
            if(v==fa)continue;
            dfs1(v,u,d+G[i].w);
            num[u]+=num[v];
            if(son[u]==-1||num[v]>num[son[u]])son[u]=v;
        }
    }
    inline void getpos(int u,int sp){
        top[u]=sp;
        p[u]=out[u]=++pos;
    
    	//cout<<u<<"ww"<<p[u]<<endl;
    
        fp[p[u]]=u;
        if(son[u]==-1)return;
        getpos(son[u],sp);
        for(int i=head[u];~i;i=G[i].next){
            int v=G[i].v;
            if(v!=son[u]&&v!=pre[u])getpos(v,v);
        }
        out[u]=pos;
    }
    
    int a[maxn];
    
    struct NODE{
    	int l,r;
    	ll sum;
    	ll add;
    }ST[maxn<<2];
    inline void pushup(int rt){
    	ST[rt].sum=ST[rt<<1].sum+ST[rt<<1|1].sum;
    }
    inline void pushdown(int rt){
    	if(ST[rt].add){
    		ST[rt<<1].sum+=ST[rt].add*(ST[rt<<1].r-ST[rt<<1].l+1);
    		ST[rt<<1|1].sum+=ST[rt].add*(ST[rt<<1|1].r-ST[rt<<1|1].l+1);
    		ST[rt<<1].add+=ST[rt].add;
    		ST[rt<<1|1].add+=ST[rt].add;
    		ST[rt].add=0;
    	}
    }
    inline void build(int l,int r,int rt){
    	if(l==r){ST[rt].l=ST[rt].r=l;ST[rt].sum=0;return;}
    	ST[rt].l=l;ST[rt].r=r;
    	int m=l+r>>1;
    	build(l,m,rt<<1);build(m+1,r,rt<<1|1);pushup(rt);
    }
    inline void update(int a,int b,int c,int l,int r,int rt){
    	if(a<=l&&b>=r){
    		ST[rt].sum+=(r-l+1)*c;
    		ST[rt].add+=c;
    		return;
    	}
    	int m=l+r>>1;
    	pushdown(rt);
    	if(a<=m)update(a,b,c,l,m,rt<<1);
    	if(b> m)update(a,b,c,m+1,r,rt<<1|1);
    	pushup(rt);
    }
    inline ll query(int x,int l,int r,int rt){
    	if(l==r){return ST[rt].sum;}
    	int m=l+r>>1;
    	pushdown(rt);
    	if(x<=m)return query(x,l,m,rt<<1);
    	else return query(x,m+1,r,rt<<1|1);
    }
    
    inline void solve(int u,int v){
    
        while(top[u]!=top[v]){
    
    		if(dep[top[u]]<dep[top[v]])swap(u,v);
            update(p[top[u]],p[u],1,1,n,1);
    		u=pre[top[u]];
        }
    
    	if(dep[u]<dep[v])swap(u,v);
    	
    	//cout<<p[u]<<"ww"<<p[v]<<endl;
        update(p[v],p[u],1,1,n,1);
    }
    
    int fa[maxn][50];
    ll falen[maxn][50];
    
    int main(){
    	//scanf("%d",&n);
    	read(n);
    	init();
    	for(int i=1;i<=n;i++){
    		//scanf("%d",&a[i]);
    		read(a[i]);
    	}
    	for(int i=2,x,y;i<=n;i++){
    		//scanf("%d%d",&x,&y);
    		read(x);read(y);
    		addedge(x,i,y);
    		fa[i][0]=x;
    		falen[i][0]=y;
    	}
    	dfs1(1,1,0);
    	getpos(1,1);
    	build(1,n,1);
    
    	for(int i=0;i<=32;i++){
    		fa[1][i]=0;
    		falen[0][i]=Linf;
    		falen[1][i]=Linf;
    	}
    	for(int i=1;i<=32;i++){
    		for(int j=1;j<=n;j++){
    			fa[j][i]=fa[fa[j][i-1]][i-1];
    			if(falen[fa[j][i-1]][i-1]==Linf){
    				falen[j][i]=Linf;continue;
    			}
    			falen[j][i]=falen[fa[j][i-1]][i-1]+falen[j][i-1];
    		}
    	}
    
    	for(int i=2;i<=n;i++){
    		int now=i;
    		for(int j=32;j>=0;j--){
    			if(falen[now][j] <= a[i]){
    				a[i]-=falen[now][j];
    				now=fa[now][j];
    			}
    			//cout<<i<<"ww"<<now<<"ww"<<a[i]<<endl;
    		}
    
    		if(i==now)continue;
    		
    		solve(fa[i][0],now);	
    	}
    	for(int i=1;i<=n;i++)printf("%lld ",query(p[i],1,n,1));
    	
    }

    A了的差分,都用的倍增

    #include<bits/stdc++.h>  
    //#pragma comment(linker, "/STACK:1024000000,1024000000")   
    #include<stdio.h>  
    #include<algorithm>  
    #include<queue>  
    #include<string.h>  
    #include<iostream>  
    #include<math.h>                    
    #include<stack>
    #include<set>  
    #include<map>  
    #include<vector>  
    #include<iomanip> 
    #include<bitset>
    using namespace std;         //
    
    #define ll long long  
    #define ull unsigned long long
    #define pb push_back  
    #define FOR(a) for(int i=1;i<=a;i++) 
    #define sqr(a) (a)*(a)
    #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
    ll qp(ll a,ll b,ll mod){
    	ll t=1;while(b){if(b&1)t=t*a%mod;b>>=1;a=a*a%mod;}return t;
    }
    struct DOT{ll x;ll y;};
    inline void read(int &x){int k=0;char f=1;char c=getchar();for(;!isdigit(c);c=getchar())if(c=='-')f=-1;for(;isdigit(c);c=getchar())k=k*10+c-'0';x=k*f;} 
    const int dx[4]={0,0,-1,1};
    const int dy[4]={1,-1,0,0};
    const int inf=0x3f3f3f3f; 
    const ll Linf=0x3f3f3f3f3f3f3f3f;
    const ll mod=1e9+7;;
    
    const int maxn=2e5+9;  
    
    int n;
     
    struct EDGE{
        int v;int w;int next;
    }G[maxn<<2];
    int head[maxn],tot;
    
    inline void addedge(int u,int v,int w){
        ++tot;G[tot].v=v;G[tot].next=head[u];G[tot].w=w;head[u]=tot;
    }
     
    /*
    int top[maxn];
    int pre[maxn];
    int dep[maxn];
    int num[maxn];	//子树尺寸
    int p[maxn];    //v的对应位置
    int out[maxn];  //退出时间戳
    int fp[maxn];   //访问序列
    int son[maxn];  //重儿子
    int pos;		//计时器
    */
    inline void init(){
        memset(head,-1,sizeof head);tot=0;
    	//memset(son,-1,sizeof son);
    }
    /*
    inline void dfs1(int u,int fa,int d){
        dep[u]=d;
        pre[u]=fa;
        num[u]=1;
        for(int i=head[u];~i;i=G[i].next){
            int v=G[i].v;
            if(v==fa)continue;
            dfs1(v,u,d+G[i].w);
            num[u]+=num[v];
            if(son[u]==-1||num[v]>num[son[u]])son[u]=v;
        }
    }
    inline void getpos(int u,int sp){
        top[u]=sp;
        p[u]=out[u]=++pos;
    
        fp[p[u]]=u;
        if(son[u]==-1)return;
        getpos(son[u],sp);
        for(int i=head[u];~i;i=G[i].next){
            int v=G[i].v;
            if(v!=son[u]&&v!=pre[u])getpos(v,v);
        }
        out[u]=pos;
    }
    */
    ll add[maxn];
    int a[maxn];
    
    /*
    struct NODE{
    	int l,r;
    	ll sum;
    	ll add;
    }ST[maxn<<2];
    inline void pushup(int rt){
    	ST[rt].sum=ST[rt<<1].sum+ST[rt<<1|1].sum;
    }
    inline void pushdown(int rt){
    	if(ST[rt].add){
    		ST[rt<<1].sum+=ST[rt].add*(ST[rt<<1].r-ST[rt<<1].l+1);
    		ST[rt<<1|1].sum+=ST[rt].add*(ST[rt<<1|1].r-ST[rt<<1|1].l+1);
    		ST[rt<<1].add+=ST[rt].add;
    		ST[rt<<1|1].add+=ST[rt].add;
    		ST[rt].add=0;
    	}
    }
    inline void build(int l,int r,int rt){
    	if(l==r){ST[rt].l=ST[rt].r=l;ST[rt].sum=0;return;}
    	ST[rt].l=l;ST[rt].r=r;
    	int m=l+r>>1;
    	build(l,m,rt<<1);build(m+1,r,rt<<1|1);pushup(rt);
    }
    inline void update(int a,int b,int c,int l,int r,int rt){
    	if(a<=l&&b>=r){
    		ST[rt].sum+=(r-l+1)*c;
    		ST[rt].add+=c;
    		return;
    	}
    	int m=l+r>>1;
    	pushdown(rt);
    	if(a<=m)update(a,b,c,l,m,rt<<1);
    	if(b> m)update(a,b,c,m+1,r,rt<<1|1);
    	pushup(rt);
    }
    inline ll query(int x,int l,int r,int rt){
    	if(l==r){return ST[rt].sum;}
    	int m=l+r>>1;
    	pushdown(rt);
    	if(x<=m)return query(x,l,m,rt<<1);
    	else return query(x,m+1,r,rt<<1|1);
    }
    
    inline void solve(int u,int v){
    
        while(top[u]!=top[v]){
    
    		if(dep[top[u]]<dep[top[v]])swap(u,v);
            update(p[top[u]],p[u],1,1,n,1);
    		u=pre[top[u]];
        }
    
    	if(dep[u]<dep[v])swap(u,v);
    	
    	//cout<<p[u]<<"ww"<<p[v]<<endl;
        update(p[v],p[u],1,1,n,1);
    }
    */
    
    int fa[maxn][50];
    ll falen[maxn][50];
    
    void dfs(int u){
    
    	for(int i=head[u];~i;i=G[i].next){
    		dfs(G[i].v);
    		add[u]+=add[G[i].v];
    	}
    }
    
    int main(){
    	//scanf("%d",&n);
    	read(n);
    	init();
    	for(int i=1;i<=n;i++){
    		//scanf("%d",&a[i]);
    		read(a[i]);
    	}
    	for(int i=2,x,y;i<=n;i++){
    		//scanf("%d%d",&x,&y);
    		read(x);read(y);
    		addedge(x,i,y);
    		fa[i][0]=x;
    		falen[i][0]=y;
    	}
    	//dfs1(1,1,0);
    	//getpos(1,1);
    	//build(1,n,1);
    
    	for(int i=0;i<=32;i++){
    		fa[1][i]=0;
    		falen[0][i]=Linf;
    		falen[1][i]=Linf;
    	}
    	for(int i=1;i<=32;i++){
    		for(int j=1;j<=n;j++){
    			fa[j][i]=fa[fa[j][i-1]][i-1];
    			if(falen[fa[j][i-1]][i-1]==Linf){
    				falen[j][i]=Linf;continue;
    			}
    			falen[j][i]=falen[fa[j][i-1]][i-1]+falen[j][i-1];
    		}
    	}
    
    	for(int i=2;i<=n;i++){
    		int now=i;
    		for(int j=32;j>=0;j--){
    			if(falen[now][j] <= a[i]){
    				a[i]-=falen[now][j];
    				now=fa[now][j];
    			}
    			//cout<<i<<"ww"<<now<<"ww"<<a[i]<<endl;
    		}
    
    		if(i==now)continue;
    		
    		//solve(fa[i][0],now);	
    		add[fa[i][0]]++;add[fa[now][0]]--;
    	}
    	dfs(1);
    	for(int i=1;i<=n;i++)printf("%lld ",add[i]);
    	//for(int i=1;i<=n;i++)printf("%lld ",query(p[i],1,n,1));
    	
    }


  • 相关阅读:
    leetcode 33. Search in Rotated Sorted Array
    leetcode 32. Longest Valid Parentheses
    leetcode 28. Implement strStr()
    leetcode 27. Remove Element
    leetcode 26. Remove Duplicates from Sorted Array
    leetcode 24. Swap Nodes in Pairs
    leetcode 22. Generate Parentheses
    树莓派的频率管理和热控制
    sql执行insert插入一条记录同时获取刚插入的id
    全程直播个人博客重构过程,采用springboot+dubbo+jpa技术栈。
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611188.html
Copyright © 2011-2022 走看看