GDCPC2009--H(线段树)

来源:互联网 发布:数据恢复 编辑:程序博客网 时间:2024/05/21 18:00

Westward JourneyOnline

(Input File: h.in /Standard Output)

 

“Westward Journey” is one of the most popular online gamesin China, which is developed and run by NIE. The game is based on the famousand romantic Chinese classical fiction “Journey to the West”, and the well-knowfilm by Stephen Chow. The story behind “Westward Journey” is fantasy and thusattracts many players.

The gamecontains many regions, and different regions are ruled by different dominators.One of the regions which named “Tree World” is now ruled by a monster. There areN castles in this region, and each of them has its importance value (a positiveinteger not larger than 108). The castles are connected by (N – 1)bidirectional roads. The roads make all the castles connected (that means youcan travel between any two castles of them). The importance values of thecastles are variable. Now, the monster wants to know something if he destroysone of the roads. In detail, you are to handle totally Q instructions: each ofthem can be one of the following forms.

 

CHANGE i w

The importance value of the ith castle was changed tow (1≤w≤108).

QUERY j

Output min1 × max1 + min2 × max2

Explanations: The jth road can divide the “Tree World” into two connected components, namedpart1 and part2. Here,

min1: the minimum importance value inpart1;

max1: the maximum importance value inpart1;

min2: the minimum importance value inpart2;

max2: the maximum importance value inpart2;

 

Input:

The firstline contains an integer T (T ≤10), the number of test cases.

For eachtest case, the first line contains two integers N (2 ≤ N ≤ 100000) and Q (1 ≤ Q≤ 100000), indicating the number ofcastles and instructions.

Thefollowing line contains N integers (positive integer not larger than 108),indicating the initial importance value of each castle (castles are numberedfrom 1 to N).

Thefollowing (N – 1) lines each contains two integers u and v, indicating castle uand castle v are connected directly by a bidirectional road (the roads arenumbered from 1 to N - 1).

Thefollowing Q lines each contains an instruction according to the specificationabove.

 

 

Output:

For each“QUERY” instruction, output the result on a separate line.

 

SampleInput:

1

53

12 3 4 5

12

23

34

45

QUERY1

CHANGE1 10

QUERY1

 

SampleOutput:

11

110

题意:给出一棵树,每个节点有点权。两种操作:一种是更改点权。另一种是询问如果删掉某条边后两棵子树的最大值最小值之积的和、

思路:TLE了好多发、、、最后因为cout的原因,改为printf就AC,囧!!!

    通过时间戳建立线段树,则每颗子树在线段树上是连续的区间。这样就很好想了,两部分,一部分在线段树上是连续的区间。另一部分就是线段树的剩余部分。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define LL long long int#define inf 0x3f3f3f3f#define maxn 100800#define maxm 200160#define lson id<<1,l,mid#define rson id<<1|1,mid+1,rint key[maxn],a[maxn],pos[maxn];int pre[maxn],Left[maxn],Right[maxn];int first[maxn];int vv[maxm],nxt[maxm];int e,cnt;int Min1,Min2,Max1,Max2;struct Edge{    int from,to;}edge[maxn];void init(){    memset(first,-1,sizeof(first));    e = cnt = 0;}void addedge(int u,int v){    vv[e] = v;  nxt[e] = first[u];  first[u] = e++;    vv[e] = u;  nxt[e] = first[v];  first[v] = e++;}inline int min(int a,int b){    return a>b?b:a;}inline int max(int a,int b){    return a>b?a:b;}struct ST{    int l,r,Min,Max;}st[maxn<<2];void PushUp(int id){    st[id].Max = max(st[id<<1].Max,st[id<<1|1].Max);    st[id].Min = min(st[id<<1].Min,st[id<<1|1].Min);}void buildtree(int id,int l,int r){    st[id].l = l,st[id].r = r;    if(l == r)    {        st[id].Min = st[id].Max = key[l];        return;    }    int mid = (l+r) >> 1;    buildtree(lson);    buildtree(rson);    PushUp(id);}void Update(int id,int pos,int k){    if(st[id].l == pos && st[id].r == pos)    {        st[id].Min = st[id].Max = k;        return;    }    if(st[id<<1].r >= pos)        Update(id<<1,pos,k);    else Update(id<<1|1,pos,k);    PushUp(id);}void Query(int id,int l,int r,int ope)//1是Max 2是Min{    if(st[id].l == l && st[id].r == r)    {        if(ope == 1)        {            Min1 = min(Min1,st[id].Min);            Max1 = max(Max1,st[id].Max);        }        else         {            Min2 = min(Min2,st[id].Min);            Max2 = max(Max2,st[id].Max);        }        return;    }    if(st[id<<1].r >= r)        Query(id<<1,l,r,ope);    else if(st[id<<1|1].l <= l)        Query(id<<1|1,l,r,ope);    else     {        Query(id<<1,l,st[id<<1].r,ope);        Query(id<<1|1,st[id<<1|1].l,r,ope);    }}void dfs(int u,int fa){    pos[u] = Left[u] = ++cnt;    pre[u] = fa;    for(int i = first[u];i != -1;i = nxt[i])    {        int v = vv[i];        if(v == fa) continue;        dfs(v,u);    }    Right[u] = cnt;}int main(){    //freopen("in.txt","r",stdin);    int t;    scanf("%d",&t);    while(t--)    {        int n,q;        scanf("%d%d",&n,&q);        for(int i = 1;i <= n;i++)   scanf("%d",&a[i]);        init();        for(int i = 1;i < n;i++)        {            int u,v;            scanf("%d%d",&u,&v);            addedge(u,v);            edge[i].from = u;            edge[i].to = v;        }        dfs(1,0);        for(int i = 1;i <= n;i++)            key[pos[i]] = a[i];        buildtree(1,1,n);        char ope[12];        while(q--)        {            scanf("%s",ope);            if(ope[0] == 'Q')            {                int k;  scanf("%d",&k);                int u = edge[k].from,v = edge[k].to;                if(pre[u] == v) swap(u,v);//现在必然是u->v                int ff = Left[v],tt = Right[v];                Min1 = inf,Min2 = inf;                Max1 = -inf,Max2 = -inf;                Query(1,ff,tt,2);                if(ff == 1)                {                    Query(1,tt+1,cnt,1);                }                else if(tt == cnt)                {                    Query(1,1,ff-1,1);                }                else                 {                    Query(1,1,ff-1,1);                    Query(1,tt+1,cnt,1);                }                LL ans = (LL)(((LL)(Min1)) * ((LL)(Max1))) + (LL)(((LL)(Min2)*((LL)(Max2))));                printf("%lld\n",ans);            }            else            {                int p,k;    scanf("%d%d",&p,&k);                Update(1,pos[p],k);            }        }    }    return 0;}                          


0 0
原创粉丝点击