HDU 4879 ZCC loves March (query set + set)

Source: Internet
Author: User

Question: a matrix with a maximum of 10 ^ 18*10 ^ 18 will give you a maximum of 100,000 soldiers in the matrix, which may have duplicate positions. Then there are two operations, one is to move the I-th soldier to the upper, lower, left, right, and the other is to move all the soldiers with the same horizontal coordinates as the I-th soldier to this point, and then calculate the cost.

I have been thinking about this question for several days. After reading some prompts for the program, I finally wrote it out. After optimization, the read speed is about 546 ms to Ms.

Practice: open two sets to maintain the same X and Y, but there will be coordinates at the same position. What should I do? Maintain vertices at the same position with the query set. The point at the same position may exist during reading, so it is necessary to use it during reading, but there is another problem, because the first step is to move the vertex, it is easy to move and check the node of the Set instead of the root node. But what if you want to move the node and check the root of the set? I cannot solve this problem .. After reading a new array in the mark process, it seems that it is added later .. I suddenly figured out that the original vertex will not be deleted. If you want to move it, add a new vertex directly and save the coordinates of the new vertex in the new one, at the same time, you need to open an NCT array to save and check several nodes in the set. If you need to move the node and check the root of the set and add a new node, the original vertex will be meaningless, however, this root is useful when the second operation merges two sets. Another point is that if you want to move the NCT value of the root of the node in the moving operation is 1, it means that this set has only one useful point, although there may be many other points. Then delete the root from the set. Note that you cannot simply judge whether the father of the node is himself or herself, because you may be the root of the node and you cannot determine whether there are any nodes below, therefore, it can only be determined by the number of nodes saved in the NCT array.

In general, implementation is really difficult ..

AC code (Added with read optimization ):

#include<cstdio>#include<ctype.h>#include<algorithm>#include<iostream>#include<cstring>#include<vector>#include<stack>#include<cmath>#include<queue>#include<set>#include<ctime>using namespace std;#define ll __int64#define MOD 1000000007const ll Max = 1e18+1;inline void scan_d(ll &ret) {    char c; ret=0;    while((c=getchar())<'0'||c>'9');    while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();}struct node{    ll x;    ll y;    int pp;    bool operator!=(const node &n1) const    {        if(n1.x == x&&n1.y == y) return 0;        return 1;    }};struct cmpx{    bool operator()(const node &n1, const node &n2) const    {        if(n1.x == n2.x) return n1.y<n2.y;        return n1.x<n2.x;    }};struct cmpy{    bool operator()(const node &n1, const node &n2) const    {        if(n1.y == n2.y) return n1.x<n2.x;        return n1.y<n2.y;    }};set<node,cmpx>s1;set<node,cmpy>s2;int fa[200010];int nct[200010],nnew[100005];node po[200010];int findit(int x){    return fa[x]!=x ? fa[x] = findit(fa[x]):x;}void mergeit(int x, int y){    x = findit(x);    y = findit(y);    nct[y] += nct[x];    fa[x] = y;}node make(ll x, ll y, int pp){    node t;t.x = x;t.y=y;t.pp=pp;return t;}int main(){    //freopen("input.txt","r",stdin);//    freopen("o.txt","w",stdout);    ll m;    int n,i,j,t;    while(~scanf("%d%I64d",&n,&m))    {        s1.clear();        s2.clear();        s1.insert(make(-1,0,0));        s1.insert(make(Max,0,0));        s2.insert(make(0,-1,0));        s2.insert(make(0,Max,0));        set<node,cmpx>::iterator itx1,itx2,tmp1;        set<node,cmpy>::iterator ity1,ity2,tmp2;        for(i = 1; i <= n; i++)        {            fa[i] = i;            scan_d(po[i].x);scan_d(po[i].y);//            scanf("%I64d%I64d",&po[i].x,&po[i].y);            nnew[i] = i;            po[i].pp = i;            itx1 = s1.find(po[i]);            if(itx1 != s1.end())            {                nct[i] = 0;                mergeit(i,itx1->pp);                nct[itx1->pp]++;            }            else            {                nct[i] = 1;                s1.insert(po[i]);                s2.insert(po[i]);            }        }        char temp;        scanf("%d\n",&t);        ll ans = 0;        while(t--)        {            scanf("%c",&temp);            ll a,b;            if(temp == 'Q')            {                scan_d(a);//                scanf("%I64d",&a);                a ^= ans;                a = nnew[a];                ans = 0;                int x = findit(a);                tmp1 = itx1 = itx2 = s1.lower_bound(po[x]);                for(;itx1->x == po[x].x;itx1--);                itx1++;                for(;itx2->x == po[x].x;itx2++);                while(itx1!=itx2)                {                    if(tmp1!=itx1)                    {                        int pos = itx1->pp;                        ans += ((ll)nct[pos]*(((itx1->y-po[x].y)%MOD*((itx1->y-po[x].y)%MOD))%MOD))%MOD;                        ans %= MOD;                        mergeit(pos,x);                        s2.erase(make(itx1->x,itx1->y,itx1->pp));                        s1.erase(itx1++);                    }                    else itx1++;                }                tmp2 = ity1 = ity2 = s2.lower_bound(po[x]);                for(;ity1->y == po[x].y;ity1--);                ity1++;                for(;ity2->y == po[x].y;ity2++);                while(ity1!=ity2)                {                    if(tmp2!=ity1)                    {                        int pos = ity1->pp;                        ans += ((ll)nct[pos]%MOD*(((ity1->x-po[x].x)%MOD*((ity1->x-po[x].x)%MOD))%MOD))%MOD;                        ans %= MOD;                        mergeit(pos,x);                        s1.erase(make(ity1->x,ity1->y,ity1->pp));                        s2.erase(ity1++);                    }                    else ity1++;                }                printf("%I64d\n",ans);            }            else            {                scan_d(a);scan_d(b);//                scanf("%I64d%I64d",&a,&b);                a ^= ans;                int newa = nnew[a];                if(temp == 'L')                {                    int k = findit(newa);                    if(nct[k] == 1)                    {                        s1.erase(po[k]);                        s2.erase(po[k]);                    }                    nct[k]--;                    node t = make(po[k].x,po[k].y-b,0);                    itx1 = s1.find(t);                    po[++n] = t;                    po[n].pp = n;                    nnew[a] = n;                    if(itx1 == s1.end())                    {                        fa[n] = n;                        s1.insert(po[n]);                        s2.insert(po[n]);                        nct[n]=1;                    }                    else                    {                        nct[n]=0;                        fa[n] = itx1->pp;                        nct[itx1->pp]++;                    }                }                if(temp == 'R')                {                    int k = findit(newa);                    if(nct[k] == 1)                    {                        s1.erase(po[k]);                        s2.erase(po[k]);                    }                    nct[k]--;                    node t = make(po[k].x,po[k].y+b,0);                    itx1 = s1.find(t);                    po[++n] = t;                    po[n].pp = n;                    nnew[a] = n;                    if(itx1 == s1.end())                    {                        fa[n] = n;                        s1.insert(po[n]);                        s2.insert(po[n]);                        nct[n]=1;                    }                    else                    {                        nct[n]=0;                        fa[n] = itx1->pp;                        nct[itx1->pp]++;                    }                }                if(temp == 'U')                {                    int k = findit(newa);                    if(nct[k] == 1)                    {                        s1.erase(po[k]);                        s2.erase(po[k]);                    }//                    cout<<k<<endl;                    nct[k]--;                    node t = make(po[k].x-b,po[k].y,0);                    itx1 = s1.find(t);                    po[++n] = t;                    po[n].pp = n;                    nnew[a] = n;                    if(itx1 == s1.end())                    {                        fa[n] = n;                        s1.insert(po[n]);                        s2.insert(po[n]);                        nct[n]=1;                    }                    else                    {                        nct[n]=0;                        fa[n] = itx1->pp;                        nct[itx1->pp]++;                    }                }                if(temp == 'D')                {                    int k = findit(newa);                    if(nct[k] == 1)                    {                        s1.erase(po[k]);                        s2.erase(po[k]);                    }//                    cout<<k<<endl;                    nct[k]--;                    node t = make(po[k].x+b,po[k].y,0);                    itx1 = s1.find(t);                    po[++n] = t;                    po[n].pp = n;                    nnew[a] = n;                    if(itx1 == s1.end())                    {                        fa[n] = n;                        s1.insert(po[n]);                        s2.insert(po[n]);                        nct[n]=1;                    }                    else                    {                        nct[n]=0;                        fa[n] = itx1->pp;                        nct[itx1->pp]++;                    }                }            }        }    }    return 0;}





Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.