zoukankan      html  css  js  c++  java
  • xj膜你赛(n-1)

    Strategy

    1.1 Background

    针针喜欢玩一款叫做 DotA (Defense of the Algorithm) 的游戏。——CTSC2018 Day1 T1 假面

    1.2 Description

    继 8102CSTC 之后,DotA 推出了新的游戏模式。在一场对战中,针针需要面对 (n(1 ≤n ≤ 4000)) 个敌人,对于第 i 个敌人针针有如下技能可以选择 (必须选择其中一种):

    • 花费 (attack_i) 的代价主动进攻,迫使敌人进入防御状态,使之无法进攻,但是在一场对战中只能攻击 (k) 次。
    • 花费 (defend_i) 的代价防御防御该敌人的进攻,该技能可以在对战中使用任意多次。
    • 与该敌人结盟。注意,结盟只能对 1 个敌人使用,此时既不能攻击该敌人,也不必防御该敌人的进攻。

    现在给定每个敌人的 (attack)(defend) , 以及最多攻击次数 (k), 针针想要知道, 在和第 (i) 个敌人结盟的情况下, 他在这一轮对战中最少花费的代价。

    1.3 Input Format

    第一行一个正整数 (n(1 ≤ n ≤ 4000)),表示敌人个数。
    接下来 (n) 行,每行两个正整数 (attack_i(1 ≤ attack_i ≤ 10^9))(defend_i(1 ≤ defend_i ≤ 10^9))

    1.4 Output Format

    一行 (n) 个整数, 第 (i) 个数表示和第 (i) 个敌人结盟时的最小代价。

    1.5 Sample Input

    4
    1 5
    2 3
    2 4
    3 5
    

    1.6 Sample Output

    8 8 7 6
    

    1.7 Guarantee

    (n ≤ 4000)

    分析

    贪心题。

    1.(O(n^2))

    先设所有的全部选 (attack) ,再暴力枚举最优方案即可。

    2.(O(nlog n))

    统计前缀和。
    本题标程的复杂度是(O(n^2log n))……

    Code

    1.(O(n^2))

    #include<cstdio>
    #include<algorithm>
    #define maxn 40002
    using namespace std;
    template<typename tp>
    tp read(){
        char c=getchar();
        bool sgn=0;
        tp x=0;
        while((c<'0'||c>'9')&&c!='-')c=getchar();
        if(c=='-')sgn=1,c=getchar();
        while(c>='0'&&c<='9'){
            x=(x<<3)+(x<<1)+c-'0';
            c=getchar();
        }
        return sgn?-x:x;
    }
    template<typename tp>
    void write(const tp x){
        if(x<0)putchar('-'),write(-x);
        else{
            write(x/10);
            putchar(x%10+'0');
        }
    }
    int n,k;
    long long a[maxn],sum;
    struct data{
        long long val;
        int pos;
        bool operator <(const data& dat)const{
            return val<dat.val;
        }
    }d[maxn];
    int main(){
        n=read<int>(),k=read<int>();
        for(int i=1;i<=n;i++){
            a[i]=read<long long>();
            d[i].val=read<long long>()-a[i];
            d[i].pos=i;
            sum+=a[i];
        }
        sort(d+1,d+n+1);
        for(int i=1;i<=n;i++){
            long long res=sum-a[i];
            int j=1,cnt=1;
            for(;cnt<n-k;j++){
                if(d[j].pos!=i)res+=d[j].val,cnt++;
            }
            for(;j<=n;j++){
                if(d[j].pos!=i){
                    if(d[j].val<0)res+=d[j].val;
                    else break;
                }
            }
            printf("%lld ",res);
        }
        return 0;
    }
    

    2.(O(nlog n))

    #include<cstdio>
    #include<algorithm>
    #define maxn 4005
    #define INF 100000000000000000ll
    using namespace std;
    long long read(){
    	char c=getchar();
    	bool sgn=0;
    	long long x=0;
    	while((c<'0'||c>'9')&&c!='-')c=getchar();
    	if(c=='-')sgn=1,c=getchar();
    	while(c>='0'&&c<='9'){
    		x=(x<<3)+(x<<1)+c-'0';
    		c=getchar();
    	}
    	return sgn?-x:x;
    }
    void write(const long long x){
    	if(x<0)putchar('-'),write(-x);
    	else{
    		if(x>=10)write(x/10);
    		putchar(x%10+'0');
    	}
    }
    struct node{
    	long long val,pos;
    }a[maxn];
    inline bool cmp(const node& x,const node& y){
    	return x.val>y.val;
    }
    long long n,k,at[maxn],c[maxn],de[maxn],dp[maxn],sumd=0,suma=0;
    bool b[maxn];
    int main(){
    	n=read(),k=read();
    	for(int i=1;i<=n;i++){
    		at[i]=read(),de[i]=read();
    		a[i].val=de[i]-at[i];
    		a[i].pos=i;
    		c[i]=a[i].val;
    		sumd+=de[i];
    	}
    	sort(a+1,a+n+1,cmp);
    	for(int i=1;i<=k;i++){
    		if(a[i].val>0){
    			b[a[i].pos]=1;
    			suma+=a[i].val;
    		}
    	}
    	for(int i=1;i<=n;i++){
    		long long ans=sumd-de[i];
    		if(b[i])ans-=suma-c[i]+(a[k+1].val>0?a[k+1].val:0);
    		else ans-=suma;
    		write(ans),putchar(' ');
    	}
    	return 0;
    }
    

    Easy LCA (easy.cpp)

    2.1 Background

    问: 如何评价 WC2018 和 CTSC2018?
    曰: 猫喜欢上树找 LCA。
    猫: 我这次有备而来。

    2.2 Description

    猫喜欢上了你家的苹果树。你家的苹果树是一个以 (1) 号点为根的,节点数为 (n(n ≤ 6*10^5))
    的有根树。猫想要把树上所有 ( ext{LCA}) 抓下来,但是他答应,只要你能回答他的一个问题,他就放过你的苹果树。
    猫会给你一个长度为 (n)(1)(n) 的排列 (p),定义连续子段 (p[l, r]) 的权值如下:

    [val[l, r] = depth[lca(pl, pl+1, . . . , pr)]$$ 也就是 $pl, pl+1, . . . , pr$ 的 $ ext{LCA}$ 的深度。他希望求出所有 $n(n+1)/2$ 个连续子段的权值和 (i.e. $sum^n_{i=1}sum^n_{j=i}val[i, j]$ )。**根节点深度为 $1$ **。 你正要用苹果树出一道题,所以为了防止猫弄坏你精心设计的苹果树,你决定回答这个问题。 ## 2.3 Input Format 第一行一个正整数 $n(1 ≤ n ≤ 6*10^5)$ 。 接下来 $n - 1$ 行,每行两个正整数 $u_i, v_i(1 ≤ u_i, v_i ≤ n)$ ,代表树上的一条边 $(u, v)$ 。 数据保证输入的是一棵合法的树。 接下来一行包含 $n$ 个正整数,代表一个 $1$ 到 $n$ 的排列 $p$ 。 ## 2.4 Output Format 输出一行一个整数,表示所求的所有连续子段的权值和。 ## 2.5 Sample Input ``` 6 1 2 2 6 6 3 3 4 6 5 1 2 3 4 5 6 ``` 2.6 Sample Output ``` 51 ``` ## 2.7 Guarantee $n ≤ 6*10^5$ ## 分析 观察样例,我们先把相邻点的 $ ext{LCA}$ 求出: 节点 1 2 3 4 5 6 $ ext{LCA}$ 1 2 3 6 6 设求出的序列为 $l$ ,则 $l_i$ 表示 $ ext{LCA}_{a_i,a_{i+1}}$ 。$dep$ 表示节点深度序列。 对于其中任意三个连续节点 $a_i,a_{i+1},a_{i+2}$ ,我们发现它们的 $ ext{LCA}$ 就是 $$dep[ ext{LCA}_{a_i,a_{i+1}}]<dep[ ext{LCA}_{a_{i+1},a_{i+2}}];?; ext{LCA}_{a_i,a_{i+1}}: ext{LCA}_{a_{i+1},a_{i+2}}]

    同样,对于任意的 (k) 个连续节点,它们的 ( ext{LCA}) 也可以用类似的方法求出。
    于是,我们枚举每一个 (l_i) ,算出它左边第一个深度小于它的节点 (l_j) 和右边第一个深度小于它的节点 (l_k) ,则以 (l_i)( ext{LCA}) 的所有区间的答案为 ((l_i-l_j+1)*(l_k-l_i+1)*dep[l_i])
    我没发现上面的问题其实就是求一个最大子矩形,用单调栈或其他一些方法 (O(n)) 求解即可。
    总时间复杂度 (O(nlog n)),瓶颈在求 ( ext{LCA}) 。空间复杂度 (O(n))

    Code

    #include<cstdio>
    #include<algorithm>
    #define maxn 1200010
    using namespace std;
    namespace FASTIO{
    	int read(){
    		char c=getchar();
    		bool sgn=0;
    		int x=0;
    		while((c<'0'||c>'9')&&c!='-')c=getchar();
    		if(c=='-')sgn=1,c=getchar();
    		while(c>='0'&&c<='9'){
    			x=(x<<3)+(x<<1)+c-'0';
    			c=getchar();
    		}
    		return sgn?-x:x;
    	}
    	void write(const long long x){
    		if(x<0)putchar('-'),write(-x);
    		else{
    			if(x>=10)write(x/10);
    			putchar(x%10+'0');
    		}
    	}
    }
    namespace TREE{
    	struct edge{
    		int to,next;
    	};
    	edge e[maxn<<1];
    	int head[maxn],cnte;
    	void add(int u,int v){
    		e[++cnte].to=v;
    		e[cnte].next=head[u];
    		head[u]=cnte;
    	}
    	int n;
    }
    using TREE::n;
    namespace LCA{
    	int lg[maxn],fa[maxn][30],dep[maxn];
    	void initlg(){
    		for(int i=1;i<=n;i++)lg[i]=lg[i-1]+((1<<lg[i-1])==i);
    	}
    	void initdfs(int u,int last){
    		dep[u]=dep[last]+1;
    		fa[u][0]=last;
    		for(int i=1;(1<<i)<dep[u];i++){
    			fa[u][i]=fa[fa[u][i-1]][i-1];
    		}
    		for(int i=TREE::head[u];i;i=TREE::e[i].next){
    			int v=TREE::e[i].to;
    			if(v==last)continue;
    			initdfs(v,u);
    		}
    	}
    	int lca(int x,int y){
    		if(dep[x]<dep[y])swap(x,y);
    		while(dep[x]>dep[y]){
    			x=fa[x][lg[dep[x]-dep[y]]-1];
    		}
    		if(x==y)return x;
    		for(int i=lg[dep[x]];i>=0;i--){
    			if(fa[x][i]!=fa[y][i]){
    				x=fa[x][i];
    				y=fa[y][i];
    			}
    		}
    		return fa[x][0];
    	}
    }
    namespace STACK{
    	int l[maxn],top,left[maxn],right[maxn],st[maxn];
    	void work1(){
    		top=0;
    		for(int i=1;i<n;i++){
    			while(top&&l[i]<=l[st[top]]){
    				right[st[top]]=i-1;
    				top--;
    			}
    			st[++top]=i;
    		}
    		while(top){
    			right[st[top]]=n-1;
    			top--;
    		}
    	}
    	void work2(){
    		top=0;
    		for(int i=n-1;i>=1;i--){
    			while(top&&l[i]<l[st[top]]){
    				left[st[top]]=i+1;
    				top--;
    			}
    			st[++top]=i;
    		}
    		while(top){
    			left[st[top]]=1;
    			top--;
    		}
    	}
    }
    int a[maxn];
    int main(){
    	n=FASTIO::read();
    	for(int i=1;i<n;i++){
    		int u=FASTIO::read(),v=FASTIO::read();
    		TREE::add(u,v);
    		TREE::add(v,u);
    	}
    	for(int i=1;i<=n;i++)a[i]=FASTIO::read();
    	LCA::initlg();
    	LCA::initdfs(1,0);
    	for(int i=1;i<n;i++)STACK::l[i]=LCA::dep[LCA::lca(a[i],a[i+1])];
    	STACK::work1();
    	STACK::work2();
    	long long ans=0;
    	for(int i=1;i<n;i++)ans+=(long long)(i-STACK::left[i]+1)*(STACK::right[i]-i+1)*STACK::l[i];
    	for(int i=1;i<=n;i++)ans+=LCA::dep[a[i]];
    	FASTIO::write(ans);
    	return 0;
    }
    
  • 相关阅读:
    trap命令
    MySQL数据库中日期中包涵零值的问题
    MySQL锁等待分析【2】
    MySQL锁等待分析【1】
    mysql日志文件相关的配置【2】
    mysql日志文件相关的配置【1】
    Linux的标准输出、标准错误输出、nohup
    mysql在关闭时的几个阶段
    MHA环境搭建【4】manager相关依赖的解决
    keepalived+httpd 做web服务的高可用
  • 原文地址:https://www.cnblogs.com/BlogOfchc1234567890/p/9924201.html
Copyright © 2011-2022 走看看