zoukankan      html  css  js  c++  java
  • HDU 4941 Magical Forest --STL Map应用

    题意: 有n*m个格子(n,m <= 2*10^9),有k(k<=10^5)个格子中有值,现在有三种操作,第一种为交换两行,第二种为交换两列,交换时只有两行或两列都有格子有值或都没有格子有值时才能交换,第三种操作是询问现在第A行第B列值为多少.

    解法:格子太大,但是k比较小,所以考虑离散一下,把行离散出来,最多10^5行,列用map存下即可。

    nowR[i] = j 时表示现在的第 i 行是原来的第 j 行, nowC表示列的

    R[]表示该行有没有值, CntC[]表示列

    然后交换时直交换上面几个东西即可。

    查询时先找到nowR[mp[A]], nowC[B],在对应原来的那一行里面找B即可,普通找不好找,索性预先把每行有的元素存起来,存到一个vector V[10^5]里面,因为要存下,所以行需要离散,然后排个序,以后就可以二分地找了。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <map>
    using namespace std;
    #define N 100007
    
    int nowR[N],R[N],b[N];
    map<int,int> mp,CntC,nowC;
    vector<pair<int,int> > V[N];
    struct Point
    {
        int x,y,c;
    }p[N];
    
    int bsearch(int i,int low,int high,int x)
    {
        while(low <= high)
        {
            int mid = (low+high)/2;
            if(V[i][mid].first == x)
                return mid;
            else if(V[i][mid].first > x)
                high = mid-1;
            else
                low = mid+1;
        }
        return low;
    }
    
    int main()
    {
        int n,m,k,i,j,T;
        int t,cs = 1;
        int op,A,B;
        scanf("%d",&t);
        while(t--)
        {
            mp.clear(); nowC.clear(); CntC.clear();
            scanf("%d%d%d",&n,&m,&k);
            for(i=1;i<=k;i++)
            {
                V[i].clear();
                scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].c);
                p[i].x++, p[i].y++;
                nowC[p[i].y] = p[i].y;
                b[i] = p[i].x;
            }
            sort(b+1,b+k+1);
            int ind = unique(b+1,b+k+1)-b-1;
            for(i=1;i<=ind;i++)
                mp[b[i]] = i;
            memset(R,0,sizeof(R));
            for(i=1;i<=k;i++)
            {
                int toR = mp[p[i].x];
                R[toR]++;
                int toC = nowC[p[i].y];
                CntC[toC]++;
                V[toR].push_back(make_pair(p[i].y,p[i].c));
            }
            for(i=0;i<=ind;i++)
            {
                nowR[i] = i;
                sort(V[i].begin(),V[i].end());
            }
            scanf("%d",&T);
            printf("Case #%d:
    ",cs++);
            while(T--)
            {
                scanf("%d%d%d",&op,&A,&B);
                A++,B++;
                if(op == 1)
                {
                    int toA = mp[A];
                    int toB = mp[B];
                    if((R[toA]&&R[toB]) || (!R[toA]&&!R[toB]))
                    {
                        swap(nowR[toA],nowR[toB]);
                        swap(R[toA],R[toB]);
                    }
                }
                else if(op == 2)
                {
                    if((CntC[A]&&CntC[B])||(!CntC[A]&&!CntC[B]))
                    {
                        swap(CntC[A],CntC[B]);
                        swap(nowC[A],nowC[B]);
                    }
                }
                else
                {
                    int nA = nowR[mp[A]];
                    int nB = nowC[B];
                    int id = bsearch(nA,0,V[nA].size()-1,nB);
                    if(id < 0 || id >= V[nA].size() || V[nA][id].first != nB)
                        puts("0");
                    else
                        printf("%d
    ",V[nA][id].second);
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    PSP
    【探路者】Final发布
    【探路者】final贡献分配
    【探路者】第六周立会报告6(总第39次)
    【探路者】第六周立会报告5(总第38次)
    【探路者】第六周立会报告4(总第37次)
    "Hello World!"团队负责人领跑衫感言
    PSP总结报告
    软件工程第十二次作业——例行报告
    Final阶段中间产物
  • 原文地址:https://www.cnblogs.com/whatbeg/p/4057894.html
Copyright © 2011-2022 走看看