zoukankan      html  css  js  c++  java
  • SPOJ

    OTOCI

    Time Limit: 1 Sec  

    Memory Limit: 256 MB

    题目连接

    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18141

    Description

    Some time ago Mirko founded a new tourist agency named "Dreams of Ice". The agency purchased N icy islands near the South Pole and now offers excursions. Especially popular are the emperor penguins, which can be found in large numbers on the islands.

    Mirko's agency has become a huge hit; so big that it is no longer cost-effective to use boats for the excursions. The agency will build bridges between islands and transport tourists by buses. Mirko wants to introduce a computer program to manage the bridge building process so that fewer mistakes are made.

    The islands are numbered 1 through N. No two islands are initially connected by bridges. The initial number of penguins on each island is known. That number may change, but will always be between 0 and 1000 (inclusive).

    Your program must handle the following three types of commands:

    • "bridge A B" – an offer was received to build a bridge between islands A and B (A and B will be different). To limit costs, your program must accept the offer only if there isn't already a way to get from one island to the other using previously built bridges. If the offer is accepted, the program should output "yes", after which the bridge is built. If the offer is rejected, the program should output "no".
    • "penguins A X" – the penguins on island A have been recounted and there are now X of them. This is an informative command and your program does not need to respond.
    • "excursion A B" – a group of tourists wants an excursion from island A to island B. If the excursion is possible (it is possible to get from island A to B), the program should output the total number of penguins the tourists would see on the excursion (including islands A and B). Otherwise, your program should output "impossible".

    Input

    The first line contains the integer N (1 ≤ N ≤ 30 000), the number of islands.

    The second line contains N integers between 0 and 1000, the initial number of penguins on each of the islands.

    The third line contains an integer Q (1 ≤ Q ≤ 300 000), the number of commands.

    Q commands follow, each on its own line.

    Output

    Output the responses to commands "bridge" and "excursion", each on its own line.

    Sample Input

    5
    4 2 4 5 6
    10
    excursion 1 1
    excursion 1 2
    bridge 1 2
    excursion 1 2
    bridge 3 4
    bridge 3 5
    excursion 4 5
    bridge 1 3
    excursion 2 4
    excursion 2 5

    Sample Output

    4
    impossible
    yes
    6
    yes
    yes
    15
    yes
    15
    16

    HINT

    题意

    让你维护一棵树

    link操作,update操作,query链上的点权和

    题解:

    就lct的基本操作啦

    这种就主要维护里面的update信息

    代码:

    //qscqesze
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <bitset>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 1205000
    #define mod 1000000007
    #define eps 1e-9
    #define e exp(1.0)
    #define PI acos(-1)
    #define lowbit(x) (x)&(-x)
    const double EP  = 1E-10 ;
    int Num;
    //const int inf=0x7fffffff;
    const ll inf=999999999;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    //*************************************************************************************
    const int MAXN = 100010;
    struct Node {
        Node *ch[2], *p; int size, value;
        int w;
        bool rev;
        Node(int t = 0);
        inline bool dir(void) {return p->ch[1] == this;}
        inline void SetC(Node *x, bool d) {
            ch[d] = x; x->p = this;
        }
        inline void Rev(void) {
            swap(ch[0], ch[1]); rev ^= 1;
        }
        inline void Push(void) {
            if (rev) {
                ch[0]->Rev();
                ch[1]->Rev();
                rev = 0;
            }
        }
        inline void Update(void) {
            value = w+ch[0]->value + ch[1]->value;
            size = ch[0]->size + ch[1]->size + 1;
        }
    }Tnull, *null = &Tnull, *fim[MAXN];
    // 要记得额外更新null的信息
    Node::Node(int _value){ch[0] = ch[1] = p = null; rev = 0;w = value = _value;}
    inline bool isRoot(Node *x) {return x->p == null || (x != x->p->ch[0] && x != x->p->ch[1]);}
    inline void rotate(Node *x) {
        Node *p = x->p; bool d = x->dir();
        p->Push(); x->Push();
        if (!isRoot(p)) p->p->SetC(x, p->dir()); else x->p = p->p;
        p->SetC(x->ch[!d], d);
        x->SetC(p, !d);
        p->Update();
    }
    inline void splay(Node *x) {
        x->Push();
        while (!isRoot(x)) {
            if (isRoot(x->p)) rotate(x);
            else {
                if (x->dir() == x->p->dir()) {rotate(x->p); rotate(x);}
                else {rotate(x); rotate(x);}
            }
        }
        x->Update();
    }
    inline Node* Access(Node *x) {
        Node *t = x, *q = null;
        for (; x != null; x = x->p) {
            splay(x); x->ch[1] = q; q = x;
        }
        splay(t); //info will be updated in the splay;
        return q;
    }
    inline void Evert(Node *x) {
        Access(x); x->Rev();
    }
    inline void link(Node *x, Node *y) {
        Evert(x); x->p = y;
    }
    inline Node* getRoot(Node *x) {
        Node *tmp = x;
        Access(x);
        while (tmp->Push(), tmp->ch[0] != null) tmp = tmp->ch[0];
        splay(tmp);
        return tmp;
    }
    // 一定要确定x和y之间有边
    inline void cut(Node *x, Node *y) {
        Access(x); splay(y);
        if (y->p != x) swap(x, y);
        Access(x); splay(y);
        y->p = null;
    }
    inline Node* getPath(Node *x, Node *y) {
        Evert(x); Access(y);
        return y;
    }
    inline void clear(void) {
        null->rev = 0; null->size = 0; null->value = 0;
    }
    
    int main()
    {
        int n=read();
        for(int i=1;i<=n;i++)
        {
            int x = read();
            fim[i] = new Node(x);
        }
        int q = read();
        char s[25];
        while(q--)
        {
            scanf("%s",s);
            if(s[0]=='e')
            {
                int x=read(),y=read();
                if(getRoot(fim[x])!=getRoot(fim[y]))
                {
                    printf("impossible
    ");continue;
                }
                Evert(fim[x]);
                Access(fim[y]);
                splay(fim[y]);
                printf("%d
    ",fim[y]->value);
            }
            if(s[0]=='b')
            {
                int x=read();
                int y=read();
                if(getRoot(fim[x])==getRoot(fim[y]))
                    puts("no");
                else
                {
                    puts("yes");
                    link(fim[x],fim[y]);
                }
            }
            if(s[0]=='p')
            {
                int x=read(),y=read();
                Evert(fim[x]);fim[x]->w = y;
                fim[x]->Update();
            }
        }
    
    }
  • 相关阅读:
    Git与GitHub(利用git上传本地文件到GitHub上面)
    PHP之上传文件upload.php
    PHP之数据库连接配置文件
    MUI 之picker,dialog,a标签——刷新页面问题(保留picker选中的数据)
    MUI自定义select down 下拉框
    Google按ESC退出全屏(带iframe网站)解决问题方案
    提高开发效率 -> 图片
    sublime text
    头脑风暴
    http://www.uupoop.com/ps/
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4846088.html
Copyright © 2011-2022 走看看