10-26

T1:给你一个树,每个点上有一个商人,商人们有一个价格,可以在这个点上卖金货物或者卖出货物,现在有m次询问,每次两个数x,y,求从x到y的最短路上,只能够买进卖出一次的话,获得的最高收益是多少。

emmmm想到了暴力算法,然而鬼知道暴力算法直接ac,简直无敌,看来数据随机生成的。

就是写一个lca,记录下来路径,从路径上通过一边,一边走一边更新最小值,并且用现在的值和最小值做差,再更新答案就行了。

#include<bits/stdc++.h>
using namespace std;

struct hehe{
    int y,next;
}e[500010];
struct haha{
    int y,next,fa,maxx,minn;
}e1[20100];
int lin[250010],lin1[250010],len=0,len1=0,fa[250010],a[250010],n,m;
bool vis[250010],vis1[250010];

inline int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch-'0'); ch=getchar();}
    return x*f;
}

inline void insert(int x,int y){
    e[++len].next=lin[x]; lin[x]=len;
    e[len].y=y;
}

inline void insert1(int x,int y){
    e1[++len1].next=lin1[x]; lin1[x]=len1;
    e1[len1].y=y;
}

int find(int x,int u){
    if(e1[u].minn>a[x]) e1[u].minn=a[x];
    if(a[x]>e1[u].maxx) e1[u].maxx=a[x];
    if(fa[x]==x || x==e1[u].fa) return x;
    int ans=find(fa[x],u);
    return ans;
}

void tarjan(int x,int u){
    vis1[x]=1;
    for(int i=lin[x];i;i=e[i].next){
        int y=e[i].y;
        if(!vis1[y]){
            tarjan(y,x);
        }
    }
    for(int i=lin1[x];i;i=e1[i].next){
        int y=e1[i].y;
        if(vis[y]){
            e1[i].fa=find(x,i);
        }
    }
    vis[x]=1;
    fa[x]=u;
}

int main(){
    freopen("gift.in","r",stdin);
    freopen("gift.out","w",stdout);
    
    n=read();
    for(int i=1;i<=n;++i) a[i]=read();
    int x,y;
    for(int i=1;i<=n-1;++i){
        x=read(); y=read();
        insert(x,y);
        insert(y,x);
    }
    m=read();
    for(int i=1;i<=m;++i){
        x=read(); y=read();
        insert1(x,y);
        insert1(y,x);
    }
    for(int i=1;i<=n;++i) fa[i]=i;
    for(int i=1;i<=m*2+1;++i){
        e1[i].maxx=-10000000;
        e1[i].minn=10000000;
    }
    memset(vis,0,sizeof(vis));
    memset(vis1,0,sizeof(vis1));
    tarjan(1,1);
    for(int i=1;i<=m*2;++i){
        if(!e1[i].fa) continue;
        int ans=find(e1[i].y,i);
        cout<<e1[i].maxx-e1[i].minn<<endl;
    }
    
    fclose(stdin); fclose(stdout);
    return 0;
}

 

T2:有两个人玩游戏,有n个字符串,每局开始,字符串为空串,然后两人轮流在末尾追加字符,保证新的字符串为箱子中某字符串的前缀,直到有一个人不能操作,不能操作的那个人就输掉当前的一轮。新一轮由上一局输的人先手。最后一局赢的人获胜。假定老师和hy都能采取最优的策略, 且老师为了彰显自己的大度让hy先手,求 hy能否获胜。

emmmm这个题看都没看懂啊,问机房的人也都说没看懂,不是很懂这个游戏的结束条件是什么,先留坑吧。

T3:对n个数进行区间加,区间乘,单个数的乘方操作。

t3比t2简单啊有没有,这线段树版子题啊。

维护两个懒标记sum加和x乘,当有乘时,数据的修改应该是(a[i]+sum)*x往下传递就行了

辣鸡造数据的,什么玩意,出的数据都是错的,std wa了8组,t了两组QwQ

posted @ 2017-10-26 16:38  assassin灬  阅读(122)  评论(0编辑  收藏  举报